Saltar al contenido principal
DHL · GLS · OCA

DHL y GLS en Odoo: el módulo OCA, qué cubre y qué te va a faltar

Hay módulo OCA para DHL Parcel y hay módulo OCA para GLS, pero no resuelven el mismo problema y en Odoo 19 solo sobrevive uno. Esto es lo que manda cada uno al transportista, leído en su código.

DHL y GLS en Odoo

En Odoo 19 hay módulo OCA de DHL Parcel y no hay módulo OCA de GLS. delivery_dhl_parcel está publicado en la rama 19.0 de OCA/l10n-spain, versión 19.0.1.0.2. delivery_gls_asm va de la 12.0 a la 18.0 y no está migrado. Si el plan era subir a Odoo 19 y seguir sacando etiquetas GLS desde el albarán, ese es el primer número a mirar.

Compruébalo tú: pide el manifiesto en cada rama y mira el código HTTP: OCA/l10n-spain/19.0/delivery_gls_asm/__manifest__.py devuelve 404; la misma ruta en 18.0 devuelve 200; y la de delivery_dhl_parcel en 19.0, también 200.

GLS o DHL: por qué no es la misma decisión

GLS España es paquetería: bultos pequeños y red de agencias. La integración se gana o se pierde en la etiqueta y en el estado, y su razón de ser es el volumen: cien etiquetas al día que nadie quiere teclear.

DHL en Odoo no es una marca: son dos productos con APIs distintas. El módulo OCA lo avisa en su readme/DESCRIPTION.md: «No es válido para otras integraciones de DHL como el Express, que usan otras APIs». Y la documentación oficial de Odoo 19, en su tabla de conectores, lista DHL Express y remata: «Other services from DHL are not supported».

La consecuencia: si tu contrato es DHL Express, el módulo OCA no te sirve y el conector nativo no viene en Community: en addons/ del repositorio público de odoo/odoo, en 17, 18 y 19, el único módulo de transportista es delivery_mondialrelay. Si es DHL Parcel España, el módulo OCA es el camino. Es una pregunta para tu comercial de DHL antes que para tu integrador.

DHL ParcelGLS
Nombre técnicodelivery_dhl_parceldelivery_gls_asm
Ramas publicadas13.0 a 19.0 (sin 16.0)12.0 a 18.0. No hay 19.0
RecogidasNoSí, con estados propios
Campos de aduanasExisten y van vacíosNo existen

Qué módulo OCA existe de verdad, y en qué repositorio

La confusión empieza en el sitio equivocado: buscas «OCA DHL Odoo» y aterrizas en OCA/delivery-carrier, el repositorio de logística de la OCA. Ahí no está: no hay módulo de DHL en ninguna rama de la 12.0 a la 19.0, y de GLS solo queda una carpeta fantasma en la 16.0 con un fichero dentro, static/description/index.html. Ni manifiesto ni código.

Los dos módulos vivos están en OCA/l10n-spain, y conviene ajustar la expectativa: en la rama 19.0 de OCA/delivery-carrier el único módulo que llama a la API de un transportista es delivery_correos_express; el resto es infraestructura. Y en la 19.0 de OCA/l10n-spain hay tres transportistas: delivery_dhl_parcel, delivery_mrw y delivery_seur_atlas.

Qué cubre cada módulo, leído en su código

En DHL Parcel todo sale de un método, _prepare_dhl_parcel_shipping: un diccionario plano que se lee en dos minutos.

  • Etiqueta en PDF, ZPL o EPL adjunta al albarán, con el AWB y el seguimiento.
  • Contra reembolso desde el total del pedido, con el reparto de gastos según el incoterm.
  • Seguro opcional, devoluciones, cierre de día por asistente y entrega antes de las 13:30.
  • Tres límites escritos en el módulo: no cotiza (su ROADMAP dice que los envíos «siempre se cotizan a 0»), nombre y dirección se recortan a 40 caracteres, y el peso mínimo que viaja es 1 kg aunque el bulto pese 200 g.

El equivalente en GLS es _prepare_gls_asm_shipping, más largo porque la API pide remitente y destinatario completos en cada llamada:

  • Servicio y franja horaria por método de envío, etiqueta PDF y etiqueta de devolución.
  • Seguimiento con historial completo y prueba de entrega adjunta al albarán.
  • Recogidas como flujo propio: doce códigos de servicio marcados como recogida, con botón y estados aparte.
  • Cancelación con guardarraíl: refresca el estado y solo anula si el envío sigue en «registrado en el transportista»; si no, lanza un error y te manda a gestionarlo por correo con GLS.
  • Sus límites: la referencia no puede pasar de 15 caracteres (GLS trunca y colisionan), tampoco cotiza, y el país del remitente está fijado a España en el código, con el comentario always 34=Spain.

Aduanas y exportación: los campos que el OCA deja vacíos

El hueco tiene una forma concreta: Odoo trae los campos y los módulos OCA no los usan. No falta la información: es que no viaja. Lo que Odoo 19 sí tiene, en stock_delivery:

  • product.template.hs_code, etiquetado «HS Code», con la ayuda «Standardized code for international shipping and goods declaration». Es la partida arancelaria.
  • product.template.country_of_origin, etiquetado «Origin of Goods», relación a res.country.
  • Una clase DeliveryCommodity — docstring literal: «Commodities information are needed for Commercial invoices with each provider» — con producto, cantidad, valor monetario y país de origen, más dos métodos que la construyen. Si el producto no tiene país de origen, se usa el del almacén que expide.

Lo que los módulos OCA hacen con eso: nada. Buscar hs_code, customs, aduana, arancel, incoterm o country_of_origin en el módulo entero de GLS devuelve cero resultados. En el de DHL Parcel sí aparecen, y ahí está lo interesante, porque aparecen vacíos:

"Incoterms": self.dhl_parcel_incoterm, # CPT paid, EXW owed "GoodsDescription": "", # [optional] "CustomsValue": "", # [optional] "CustomsCurrency": "", # [optional]

delivery_dhl_parcel · models/delivery_carrier.py · _prepare_dhl_parcel_shipping

Tres campos previstos por la API y los tres enviados vacíos: valor declarado, divisa y descripción de la mercancía. El incoterm sí viaja, pero fíjate de dónde sale — de self, del método de envío, no del albarán — y en el código solo hay dos valores, CPT y EXW: uno fijo para todo ese transportista. En GLS el equivalente es el campo declarado, que también sale vacío. Y ninguno de los cuatro transportistas que quedan en la 19.0 de esos dos repositorios — DHL Parcel, MRW, SEUR y Correos Express — menciona DeliveryCommodity, hs_code ni country_of_origin: la tubería que Odoo dejó preparada está sin conectar.

Lo que te falta el día que exportas:

  • Partida arancelaria y país de origen, por línea. Existen en el producto, no salen hacia el transportista.
  • Valor declarado y su divisa. Previsto en la API de DHL Parcel. Se manda vacío.
  • Descripción de la mercancía. Campo previsto. Se manda vacío.
  • Documento comercial. Una proforma generada desde el albarán y adjunta al envío. No existe en ninguno.
  • Incoterm por envío. Existe por transportista, y con dos valores.

No es un descuido de estos dos: es el patrón. delivery_schenker manda "customsClearance": False con el comentario «Customs Clearance not supported for now as it needs a full customs implementation», y su ROADMAP incluye el despacho aduanero entre lo no soportado; ese módulo llega a la 18.0 y tampoco está en la 19.0. Cuando un módulo OCA sí hace aduanas de verdad, no lo resuelve con un campo: añade un modelo propio con partida y país de origen por línea de mercancía. Esa es la medida real del trabajo.

Qué pasa cuando falta uno de esos campos

Nada, y ese es el problema. Los campos son opcionales en la API: el transportista acepta la expedición, devuelve seguimiento y la etiqueta sale por la impresora. En Odoo el albarán queda validado y en verde. El fallo ocurre después, en el despacho de aduanas en destino: el paquete se para y alguien de tu empresa teclea a mano la partida, la descripción y el valor que le pide el transportista. Silencioso en Odoo y ruidoso en atención al cliente.

Conviene ser exacto sobre cuándo aplica. No de Barcelona a Múnich: la UE es mercado interior y ahí no hay frontera aduanera. Aplica al salir del territorio — Reino Unido, Suiza, Noruega, Andorra, Turquía — y, sin salir de España, en Canarias, Ceuta y Melilla. La Ley 37/1992 del IVA lo dice en su artículo 3: excluye Ceuta y Melilla «en cuanto territorios no comprendidos en la Unión Aduanera» y Canarias «en cuanto territorios excluidos de la armonización de los impuestos sobre el volumen de negocios».

Y tampoco esperes un umbral por debajo del cual el trámite desaparezca. En el lado de la importación, que es el que la norma española detalla, el Real Decreto-ley 7/2021 (BOE-A-2021-6872) transpuso el paquete de IVA del comercio electrónico con efectos desde el 1 de julio de 2021: suprimió la exención de las importaciones de bienes de escaso valor «hasta los 22 euros de valor global de la mercancía», y explica que hasta 150 euros de valor intrínseco «se aplica la franquicia aduanera por lo que no se exige una declaración completa ante la Aduana en el momento de la importación». Léelo al revés: por debajo de 150 euros la declaración es más corta, no es cero. Y quien tiene que rellenarla sigue necesitando descripción, valor y partida: justo los campos que el módulo manda vacíos.

Cuándo el OCA basta y cuándo necesitas algo más

El módulo OCA es la respuesta correcta si envías dentro de la UE sin cruzar frontera aduanera, si lo que quieres es dejar de teclear direcciones y no una tarifa exacta en el pedido, y si estás en Odoo 18 o anterior — o en 19 con DHL Parcel.

Necesitas algo más si:

  • Exportas con regularidad, o mandas a Canarias, Ceuta o Melilla. El trabajo no es «instalar el módulo»: es poblar hs_code y país de origen, extender el payload y generar el documento comercial.
  • Estás en Odoo 19 con GLS: hoy no hay módulo, así que o se migra delivery_gls_asm o se cambia de vía.
  • Tu contrato es DHL Express, o expides con GLS desde fuera de España.

Una nota de método para cerrar: extender un módulo OCA es la vía barata cuando el hueco es un campo, y deja de serlo cuando el hueco es un documento. Meter la partida y el país de origen en el payload es heredar _prepare_dhl_parcel_shipping y añadir veinte líneas. Generar una proforma que cuadre con contabilidad ya es un módulo, con plantilla, pruebas y mantenimiento en tres versiones.

Preguntas frecuentes

¿Hay módulo OCA de DHL para Odoo 19?

Sí: delivery_dhl_parcel, en OCA/l10n-spain, versión 19.0.1.0.2. No está en OCA/delivery-carrier, donde casi todos lo buscan, y solo sirve para la API de DHL Parcel: no para DHL Express.

¿Y de GLS?

En Odoo 19 no. delivery_gls_asm está publicado de la rama 12.0 a la 18.0 en OCA/l10n-spain; en la 19.0 no existe.

Si falta el valor declarado, ¿me da error Odoo?

No: son opcionales en la API. El envío se registra, la etiqueta se genera y el albarán queda validado; el problema aparece en el despacho de aduanas en destino, ya fuera de Odoo.

Seguir por aquí

Logística en OdooExpedición, etiquetas y trackingImplantación de módulos OCAInstalar, extender y mantenerFicha del módulo DHL ParcelAlcance, versiones y flujoFicha del módulo GLSAlcance, versiones y flujoGLS en Odoo, en detalleEl transportista desde el albaránMódulo nativo o módulo OCACómo decidir en logística

Lo que hacemos sobre esto

Conector DHLQué hace, capturas, versiones y precio.

¿Exportas y el módulo se te queda corto?

Miramos tu contrato, la API que te han dado y el catálogo, y te decimos si se arregla extendiendo el módulo OCA o hace falta desarrollo propio.

Hablar con un ingeniero