Saltar al contenido principal
SEUR · Odoo

Conectar SEUR con Odoo: qué pide la API, qué falla y cuándo compensa

Sí: hay un módulo OCA gratuito que conecta SEUR con Odoo y crea la expedición al validar el albarán. Aquí está qué credenciales pide la API Atlas, qué devuelve, qué no cubre y los tres sitios exactos donde la integración se rompe en producción.

Conector SEUR para Odoo

Sí, SEUR se conecta con Odoo, y para el caso base sin desarrollo a medida: el módulo delivery_seur_atlas del repositorio OCA l10n-spain, AGPL-3, para Odoo 15 a 19. Habla con la API Atlas por REST, crea la expedición al validar el albarán, adjunta la etiqueta al picking y escribe el código de envío en carrier_tracking_ref. Lo que nadie cuenta es qué credenciales pide, qué pasa con el multibulto y el reembolso, y por qué el seguimiento a veces no vuelve.

Todo lo técnico de aquí sale de leer el código, no de un folleto: delivery_seur_atlas 19.0.1.0.0 en OCA/l10n-spain, más delivery_state, delivery_package_number y delivery_price_method en la rama 19.0 de OCA/delivery-carrier. Campos, formatos, endpoints y códigos de evento están citados tal cual aparecen en el módulo.

¿Se puede conectar SEUR con Odoo?

Sí. El módulo añade «Seur Atlas» a la lista de proveedores del método de envío y, a partir de ahí, SEUR es un transportista más dentro de Inventario. Depende de tres módulos OCA de delivery-carrierdelivery_package_number, delivery_price_method y delivery_state— y sin los tres no instala.

La pregunta útil no es si se puede, sino qué cubre. Cubre alta de expedición, etiqueta, número de seguimiento en el albarán, enlace de rastreo, anulación e histórico de estados. No cubre tarifas, reembolso ni medidas reales de paquete. El resto del artículo es el detalle de esas dos listas.

Qué hace falta antes de tocar Odoo

Contrato con SEUR y credenciales de Atlas, que no salen de un panel de autoservicio: el README del módulo dice que las pidas a tu oficina de SEUR. Son seis campos y conviene tenerlos los seis antes de abrir el método de envío.

Campo del móduloQué es
seur_atlas_vatNIF de la cuenta. Se rellena solo con el de la compañía.
seur_atlas_account_codeCódigo de cuenta: dos números separados por un guion. El guion importa (ver el tracking).
seur_atlas_usernameUsuario del contrato.
seur_atlas_passwordContraseña de ese usuario.
seur_atlas_clientCódigo de cliente. Viaja como client_id.
seur_atlas_secretSecreto. Viaja como client_secret. No es la contraseña.

Usuario y contraseña por un lado, client_id y client_secret por otro: cuatro secretos, no dos. El módulo los pide con los nombres de Odoo —usuario, contraseña, cliente, secreto—, que no tienen por qué coincidir con los del contrato: conviene mapearlos antes de rellenar nada.

# 1. Token: la peticion que hace el modulo antes de cualquier otra POST https://servicios.apipre.seur.io/pic_token grant_type=password client_id=<Client> client_secret=<Secret> username=<Username> password=<Password> -> access_token # el modulo documenta 30 segundos de vida # 2. Resto de llamadas, con Bearer <access_token> POST /pic/v1/shipments # crea la expedicion GET /pic/v1/labels # descarga la etiqueta POST /pic/v1/shipments/cancel # anula GET /pic/v1/tracking-services/extended # historico de estados # Hosts que tiene que ver tu Odoo (puerto 443) test servicios.apipre.seur.io prod servicios.api.seur.io

Dos detalles que salen caros. El entorno del método de envío decide si se llama a apipre o a api, y no es una casilla: es el botón de la cabecera que alterna entre Test Environment y Production Environment. Si se queda en pruebas, expides contra apipre y esas etiquetas no valen. Y el timeout por defecto es de 5 segundos, cambiable con el parámetro seur_atlas_timeout; con latencia se queda corto y el almacén ve un error que no lo es.

Qué se genera al validar y en qué formato sale la etiqueta

Al pulsar Validar, el módulo manda la expedición, recibe un shipmentCode, lo escribe en el campo de seguimiento del picking y descarga las etiquetas, que quedan como adjuntos del albarán. Ningún portal aparte: lo único que se interpone es el asistente de bultos, y solo cuando el albarán no trae paquetes hechos.

  • Formato: PDF, ZPL o A4 troquelado.
  • Plantilla: NORMAL, CUSTOM_REFERENCE, Z4_ONE_BODY, Z4_TWO_BODIES o GEOLABEL. Cambia el diseño, no el formato del fichero.
  • Salida: el fichero, un enlace de descarga o los dos. Con «enlace» no te llega la etiqueta, te llega una URL.
  • QR AZTEC: hay casilla, pero el propio campo avisa de que solo vale para recogidas ECB.

El detalle que quema: el ZPL no se guarda como PDF ni como .zpl, sino como adjunto .txt en ISO-8859-15, a propósito, porque SEUR manda la etiqueta con la instrucción ^CI10. Si tu cola de impresión lo reconvierte a UTF-8, los acentos del destinatario salen rotos: el fichero es correcto, el intermediario lo estropea.

Albarán de Odoo con la etiqueta del transportista adjunta y el número de seguimiento en el picking
Albarán real en producción: la etiqueta llega como adjunto al picking y el seguimiento queda en el albarán, no en un portal aparte. La captura es de un envío nuestro con Correos Express, porque no publicamos una etiqueta real de SEUR; el patrón en Odoo es el mismo: adjunto más carrier_tracking_ref.

El fallo de configuración más frecuente. El módulo no calcula tarifas: su método de tarificación levanta un NotImplementedError. Y el campo Price method de delivery_price_method viene por defecto en «Carrier obtained price». Si lo dejas así y algo le pide precio a Odoo —la tienda, el botón de añadir envío al pedido—, revienta. Hay que ponerlo en Precio fijo o Basado en reglas.

Multibulto: el caso que rompe las integraciones ingenuas

El módulo manda una lista de bultos construida a partir de number_of_packages, el entero que aporta delivery_package_number y que un asistente pide al validar. El problema es lo que va dentro de cada bulto.

  • El peso se reparte a partes iguales: el peso del envío dividido entre el número de bultos. Dos bultos de 2 y 18 kg se declaran como 10 y 10.
  • Las medidas van a 1×1×1. Literalmente, en el código, con un TODO al lado reconociéndolo. Con eso, las medidas que recibe SEUR no son las del bulto real: cualquier cálculo suyo que dependa del volumen parte de un dato que el módulo se ha inventado.
  • Si el número de bultos es cero, la lista se va vacía. El campo tiene 0 por defecto: si el tipo de operación no pregunta por bultos, o alguien valida desde código, se manda una expedición sin bultos.

Y la vuelta, que es donde duele en soporte: la respuesta que el propio test del módulo reproduce trae tres cosas —shipmentCode, ecbs y parcelNumbers— y el código solo lee la primera. Si un cliente reclama un bulto de seis, quien atiende no tiene su número. Las etiquetas sí vuelven una por bulto: cada una con su código de bulto, que es lo que da nombre al adjunto, y un campo pack del tipo «1/6» que el módulo ni mira.

Contra reembolso: qué campo lo lleva y qué pasa si falta

Respuesta corta: ninguno. El envío que se manda a SEUR no lleva importe de reembolso. Lo único parecido es un campo charges fijado a «P» en el código, que dice quién paga el porte: «P» la empresa, «D» el destinatario. No hay casilla para cambiarlo y el comentario del código lo admite. Eso es el porte, no el reembolso.

Ficha de método de envío en Odoo con las casillas Pago contra reembolso y Nivel de integración
Método de envío de nuestro propio Odoo: el proveedor que se ve es MRW, pero los dos campos son de Odoo y salen igual con Seur Atlas. «Pago contra reembolso» es un campo de Odoo, no del conector: deja al cliente elegir esa forma de pago y no viaja a la API. «Nivel de integración» tiene que estar en Obtener tarifas y crear envío —que es como viene por defecto— o la pestaña de credenciales de Atlas ni se ve.

Qué pasa si falta: la expedición sale sin reembolso, el repartidor entrega sin cobrar y te enteras tarde, por el histórico de eventos. El módulo traduce los códigos de SEUR que rodean el reembolso —LI534 «comprobar si es reembolso», LI541 «sin efectivo a la entrega», LI552 «no aceptan reembolso»—, así que los eventos llegan; el importe es lo que no se manda nunca. Si vendes así, esto es desarrollo, no configuración.

Por qué el tracking no siempre vuelve a Odoo

Tres motivos, todos en el código, y ninguno es «la API va mal».

1. Es un cron diario, no tiempo real

delivery_state instala una acción planificada, «Update deliveries states», con intervalo de un día. Recorre los albaranes en estado Hecho cuyo estado de transportista no sea ya entregado, anulado o «sin más actualizaciones». Si esperas ver el estado diez minutos después de expedir, no va a pasar: o bajas el intervalo, o pulsas el botón en el albarán. Quien habla de «tracking en tiempo real» no ha mirado el cron.

2. Pregunta por tu referencia, no por el código de SEUR

La consulta va con tipo de referencia REFERENCE y, como referencia, el nombre del albarán (WH/OUT/00042), no el código de expedición que devolvió SEUR. Si la expedición se dio de alta fuera de Odoo, se creó en el portal con otra referencia o el albarán se renombró, SEUR no devuelve nada y el módulo sale en silencio: ni estado, ni error, ni aviso. Parece que funciona. Además el código de cuenta se parte por el guion para sacar cuenta y unidad de negocio: sin guion, la llamada ni se hace.

3. El estado que intenta escribir ya no existe

Este es el bueno. El módulo traduce 403 códigos de evento de SEUR a los estados de delivery_state. De ellos, 101 apuntan al valor incidence, igual que el valor por defecto para cualquier código desconocido. Y incidence ya no está en esa lista: la rama 15.0 de delivery_state lo tenía, la 16.0 lo renombró a incident y ahí sigue en la 19.0, mientras que el módulo de SEUR no lo cambió en ninguna de sus cinco ramas. Un campo de selección de Odoo no acepta un valor que no esté en su lista: levanta un ValueError. Hay un código, LI730, que además apunta a la cadena literal «SEE MESSAGE», que tampoco es un valor válido.

Traducido a almacén: mientras todo va bien, el tracking vuelve. En cuanto un envío entra en incidencia —ausente, dirección desconocida, retenido en aduana— o llega un código que el módulo no conoce, la actualización de ese albarán se cae. Desde el cron, el error se guarda en un campo del picking y se avisa en el canal de administración, donde nadie mira; desde el botón, te salta a la cara. Es el patrón exacto de la queja: «el tracking va… hasta que hay un problema». Y no salta en las pruebas porque el único test del módulo simula un código que mapea a «en tránsito».

Antes de depurar nada, activa el registro en el método de envío. Tampoco es una casilla: es el botón de la cabecera que pone No debug hasta que lo pulsas y pasa a Debug requests. El módulo llama al registro en cada petición, pero Odoo solo escribe en ir.logging con eso activado. Sin ello no tienes ni la petición ni la respuesta de SEUR: estás adivinando.

Cuándo compensa integrar y cuándo no

No es cuestión de tamaño de empresa, sino de dónde está el trabajo repetido. El criterio que usamos:

  • Todavía no compensa por debajo de una decena de envíos al día con un solo servicio, un bulto y sin reembolso: el mantenimiento se comería el ahorro.
  • Empieza a compensar en cuanto alguien retranscribe direcciones al portal: cada retranscripción es una entrega fallida en potencia, y una entrega fallida se paga dos veces en portes.
  • Compensa claramente con más de un servicio SEUR que haya que acertar, multibulto habitual, soporte respondiendo «¿dónde está?» fuera de Odoo, o porte facturado que quieres en el pedido y no en una hoja de cálculo.

Y lo que hay que presupuestar aunque el módulo sea libre: parchear el mapeo de estados, añadir el reembolso, mandar medidas reales de paquete si algún día quieres tarifas y bajar el cron. Es un punto de partida honesto, no un producto terminado.

Si has llegado queriendo decidir entre SEUR y otro transportista, esa comparación no toca aquí: se decide por operativa y contrato, no por API. Está separada en logística en Odoo y en módulo nativo frente a OCA.

Preguntas frecuentes

¿Se puede conectar SEUR con Odoo sin desarrollo a medida?

Sí para el caso base: un servicio, un bulto, etiqueta y seguimiento. Hace falta desarrollo si vendes contra reembolso, si quieres que SEUR te tarifique o si necesitas los números de seguimiento por bulto.

¿En qué formato sale la etiqueta de SEUR en Odoo?

PDF, ZPL o A4 troquelado, con cinco plantillas, adjunta al albarán y una por bulto. El ZPL se guarda como fichero de texto en ISO-8859-15, no en UTF-8: si algo lo reconvierte, los acentos se rompen al imprimir.

¿Por qué el albarán no actualiza el estado del envío?

Tres motivos: la actualización va por un cron diario; la consulta se hace por el nombre del albarán y no por el código de expedición, así que cualquier desajuste devuelve vacío en silencio; y el estado de incidencia usa un valor que el módulo delivery_state renombró en su rama 16.0, de modo que falla justo cuando hay una incidencia.

Enlaces útiles

Logística en OdooCómo se monta el flujo de expedición completoMódulo SEUR AtlasFicha del conector OCA y su alcanceMódulos OCA en producciónQué revisar antes de instalar unoAutomatizar etiquetas y trackingEl flujo sin copiar y pegar, paso a pasoNativo frente a OCAQué transportista conviene resolver con cada unoIntegraciones y automatizaciónEl resto de conectores que mantenemos

Lo que hacemos sobre esto

Integraciones a medidaQué hace, capturas, versiones y precio.

¿Quieres SEUR dentro de tu Odoo?

Miramos tu contrato, tu volumen y tu flujo real de almacén, y te decimos qué se resuelve con configuración y qué hay que desarrollar. Sin vender módulo antes de mirar.

Hablar con un ingeniero