Sim, a SEUR liga-se ao Odoo e, para o caso base, sem desenvolvimento à medida: o módulo delivery_seur_atlas do repositório OCA l10n-spain, AGPL-3, para Odoo 15 a 19. Comunica com a API Atlas por REST, cria a expedição ao validar a guia de remessa, anexa a etiqueta ao picking e escreve o código de envio em carrier_tracking_ref. O que ninguém conta é que credenciais pede, o que acontece com o multivolume e o reembolso, e porque é que o seguimento por vezes não volta.
Tudo o que é técnico aqui sai de ler o código, não de um folheto: delivery_seur_atlas 19.0.1.0.0 em OCA/l10n-spain, mais delivery_state, delivery_package_number e delivery_price_method no ramo 19.0 de OCA/delivery-carrier. Campos, formatos, endpoints e códigos de evento estão citados tal como aparecem no módulo.
É possível ligar a SEUR ao Odoo?
Sim. O módulo acrescenta «Seur Atlas» à lista de fornecedores do método de envio e, a partir daí, a SEUR é mais uma transportadora dentro de Inventário. Depende de três módulos OCA de delivery-carrier (delivery_package_number, delivery_price_method e delivery_state) e sem os três não instala.
A pergunta útil não é se é possível, mas o que cobre. Cobre registo da expedição, etiqueta, número de seguimento na guia de remessa, ligação de rastreio, anulação e histórico de estados. Não cobre tarifas, reembolso nem medidas reais do volume. O resto do artigo é o detalhe destas duas listas.
O que é preciso antes de mexer no Odoo
Contrato com a SEUR e credenciais do Atlas, que não saem de um painel de autoatendimento: o README do módulo diz para as pedir ao seu escritório da SEUR. São seis campos e convém tê-los todos antes de abrir o método de envio.
| Campo do módulo | O que é |
|---|---|
seur_atlas_vat | NIF da conta. Preenche-se sozinho com o da empresa. |
seur_atlas_account_code | Código de conta: dois números separados por um hífen. O hífen é importante (ver o tracking). |
seur_atlas_username | Utilizador do contrato. |
seur_atlas_password | Palavra-passe desse utilizador. |
seur_atlas_client | Código de cliente. Viaja como client_id. |
seur_atlas_secret | Segredo. Viaja como client_secret. Não é a palavra-passe. |
Utilizador e palavra-passe por um lado, client_id e client_secret por outro: quatro segredos, não dois. O módulo pede-os com os nomes do Odoo (utilizador, palavra-passe, cliente, segredo), que não têm de coincidir com os do contrato: convém mapeá-los antes de preencher o que quer que seja.
# 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.ioDois detalhes que saem caros. O ambiente do método de envio decide se se chama apipre ou api, e não é uma caixa de seleção: é o botão do cabeçalho que alterna entre Test Environment e Production Environment. Se ficar em testes, expede contra apipre e essas etiquetas não valem. E o timeout por defeito é de 5 segundos, alterável com o parâmetro seur_atlas_timeout; com latência fica curto e o armazém vê um erro que não o é.
O que se gera ao validar e em que formato sai a etiqueta
Ao premir Validar, o módulo envia a expedição, recebe um shipmentCode, escreve-o no campo de seguimento do picking e descarrega as etiquetas, que ficam como anexos da guia de remessa. Nenhum portal à parte: a única coisa que se interpõe é o assistente de volumes, e só quando a guia de remessa não traz volumes feitos.
- Formato: PDF, ZPL ou A4 picotado.
- Modelo:
NORMAL,CUSTOM_REFERENCE,Z4_ONE_BODY,Z4_TWO_BODIESouGEOLABEL. Muda o desenho, não o formato do ficheiro. - Saída: o ficheiro, uma ligação de descarga ou ambos. Com «ligação» não recebe a etiqueta, recebe um URL.
- QR AZTEC: há uma caixa de seleção, mas o próprio campo avisa de que só serve para recolhas ECB.
O detalhe que queima: o ZPL não se guarda como PDF nem como .zpl, mas como anexo .txt em ISO-8859-15, de propósito, porque a SEUR envia a etiqueta com a instrução ^CI10. Se a sua fila de impressão o reconverte para UTF-8, os acentos do destinatário saem estragados: o ficheiro está correto, o intermediário é que o estraga.

carrier_tracking_ref.A falha de configuração mais frequente. O módulo não calcula tarifas: o seu método de tarifação levanta um NotImplementedError. E o campo Price method de delivery_price_method vem por defeito em «Carrier obtained price». Se o deixar assim e algo pedir preço ao Odoo (a loja, o botão de adicionar envio à encomenda), rebenta. Tem de o pôr em Preço fixo ou Baseado em regras.
Multivolume: o caso que parte as integrações ingénuas
O módulo envia uma lista de volumes construída a partir de number_of_packages, o inteiro que fornece delivery_package_number e que um assistente pede ao validar. O problema é o que vai dentro de cada volume.
- O peso reparte-se em partes iguais: o peso do envio dividido pelo número de volumes. Dois volumes de 2 e 18 kg são declarados como 10 e 10.
- As medidas vão a 1×1×1. Literalmente, no código, com um TODO ao lado a reconhecê-lo. Com isso, as medidas que a SEUR recebe não são as do volume real: qualquer cálculo seu que dependa do volume parte de um dado que o módulo inventou.
- Se o número de volumes for zero, a lista vai vazia. O campo tem 0 por defeito: se o tipo de operação não pergunta por volumes, ou alguém valida a partir de código, envia-se uma expedição sem volumes.
E o regresso, que é onde dói no suporte: a resposta que o próprio teste do módulo reproduz traz três coisas (shipmentCode, ecbs e parcelNumbers) e o código só lê a primeira. Se um cliente reclamar um volume de seis, quem atende não tem o seu número. As etiquetas, sim, voltam uma por volume: cada uma com o seu código de volume, que é o que dá nome ao anexo, e um campo pack do tipo «1/6» que o módulo nem olha.
Contra reembolso: que campo o leva e o que acontece se faltar
Resposta curta: nenhum. O envio que se manda à SEUR não leva montante de reembolso. A única coisa parecida é um campo charges fixado em «P» no código, que diz quem paga o porte: «P» a empresa, «D» o destinatário. Não há caixa para o alterar e o comentário do código admite-o. Isso é o porte, não o reembolso.

O que acontece se faltar: a expedição sai sem reembolso, o estafeta entrega sem cobrar e só se apercebe tarde, pelo histórico de eventos. O módulo traduz os códigos da SEUR que rodeiam o reembolso (LI534 «verificar se é reembolso», LI541 «sem dinheiro na entrega», LI552 «não aceitam reembolso»), pelo que os eventos chegam; o montante é o que nunca se envia. Se vende assim, isto é desenvolvimento, não configuração.
Porque é que o tracking nem sempre volta ao Odoo
Três motivos, todos no código, e nenhum é «a API está a falhar».
1. É um cron diário, não tempo real
delivery_state instala uma ação agendada, «Update deliveries states», com intervalo de um dia. Percorre as guias de remessa em estado Feito cujo estado de transportadora não seja já entregue, anulado ou «sem mais atualizações». Se espera ver o estado dez minutos depois de expedir, isso não vai acontecer: ou reduz o intervalo, ou prime o botão na guia de remessa. Quem fala de «tracking em tempo real» não olhou para o cron.
2. Pergunta pela sua referência, não pelo código da SEUR
A consulta vai com tipo de referência REFERENCE e, como referência, o nome da guia de remessa (WH/OUT/00042), não o código de expedição que a SEUR devolveu. Se a expedição foi registada fora do Odoo, foi criada no portal com outra referência ou a guia de remessa foi renomeada, a SEUR não devolve nada e o módulo sai em silêncio: nem estado, nem erro, nem aviso. Parece que funciona. Além disso, o código de conta é partido pelo hífen para obter conta e unidade de negócio: sem hífen, a chamada nem se faz.
3. O estado que tenta escrever já não existe
Este é o bom. O módulo traduz 403 códigos de evento da SEUR para os estados de delivery_state. Destes, 101 apontam para o valor incidence, tal como o valor por defeito para qualquer código desconhecido. E incidence já não está nessa lista: o ramo 15.0 de delivery_state tinha-o, o 16.0 renomeou-o para incident e aí continua no 19.0, enquanto o módulo da SEUR não o mudou em nenhum dos seus cinco ramos. Um campo de seleção do Odoo não aceita um valor que não esteja na sua lista: levanta um ValueError. Há um código, LI730, que além disso aponta para a cadeia literal «SEE MESSAGE», que também não é um valor válido.
Traduzido para armazém: enquanto tudo corre bem, o tracking volta. Assim que um envio entra em incidência (ausente, morada desconhecida, retido na alfândega) ou chega um código que o módulo não conhece, a atualização dessa guia de remessa falha. A partir do cron, o erro é guardado num campo do picking e avisa-se no canal de administração, onde ninguém olha; a partir do botão, salta-lhe à cara. É o padrão exato da queixa: «o tracking funciona… até haver um problema». E não salta nos testes porque o único teste do módulo simula um código que mapeia para «em trânsito».
Antes de depurar seja o que for, ative o registo no método de envio. Também não é uma caixa de seleção: é o botão do cabeçalho que diz No debug até o premir e passa a Debug requests. O módulo chama o registo em cada pedido, mas o Odoo só escreve em ir.logging com isso ativo. Sem isso não tem nem o pedido nem a resposta da SEUR: está a adivinhar.
Quando compensa integrar e quando não
Não é uma questão de dimensão da empresa, mas de onde está o trabalho repetido. O critério que usamos:
- Ainda não compensa abaixo de uma dezena de envios por dia com um só serviço, um volume e sem reembolso: a manutenção comeria a poupança.
- Começa a compensar assim que alguém retranscreve moradas no portal: cada retranscrição é uma entrega falhada em potência, e uma entrega falhada paga-se duas vezes em portes.
- Compensa claramente com mais de um serviço SEUR que tenha de acertar, multivolume habitual, suporte a responder «onde está?» fora do Odoo, ou porte faturado que quer na encomenda e não numa folha de cálculo.
E o que tem de orçamentar mesmo que o módulo seja livre: corrigir o mapeamento de estados, acrescentar o reembolso, enviar medidas reais de volume se algum dia quiser tarifas e reduzir o cron. É um ponto de partida honesto, não um produto acabado.
Se chegou aqui a querer decidir entre a SEUR e outra transportadora, essa comparação não cabe aqui: decide-se por operativa e contrato, não por API. Está separada em logística no Odoo e em módulo nativo versus OCA.
Perguntas frequentes
É possível ligar a SEUR ao Odoo sem desenvolvimento à medida?
Sim para o caso base: um serviço, um volume, etiqueta e seguimento. É preciso desenvolvimento se vende contra reembolso, se quer que a SEUR lhe tarife ou se precisa dos números de seguimento por volume.
Em que formato sai a etiqueta da SEUR no Odoo?
PDF, ZPL ou A4 picotado, com cinco modelos, anexa à guia de remessa e uma por volume. O ZPL guarda-se como ficheiro de texto em ISO-8859-15, não em UTF-8: se algo o reconverter, os acentos estragam-se ao imprimir.
Porque é que a guia de remessa não atualiza o estado do envio?
Três motivos: a atualização vai por um cron diário; a consulta faz-se pelo nome da guia de remessa e não pelo código de expedição, pelo que qualquer desajuste devolve vazio em silêncio; e o estado de incidência usa um valor que o módulo delivery_state renomeou no seu ramo 16.0, pelo que falha precisamente quando há uma incidência.
Ligações úteis
O que fazemos sobre isto
Quer a SEUR dentro do seu Odoo?
Analisamos o seu contrato, o seu volume e o seu fluxo real de armazém, e dizemos-lhe o que se resolve com configuração e o que tem de ser desenvolvido. Sem vender módulo antes de analisar.

