Ao validar uma guia com transportadora, o Odoo automatiza quatro coisas: a chamada à API, a etiqueta PDF anexada à guia, o número de seguimento em carrier_tracking_ref e o e-mail ou SMS ao cliente com esse número. Não automatiza a recolha física nem a verdade do peso e dos volumes. Aqui fica o fluxo com o modelo do Odoo de cada passo e o código dos nossos conectores de Correos Express e MRW, que usamos no nosso próprio armazém. Sem Odoo por trás, o mesmo está em integrar a API de uma transportadora num site próprio.
Ideia-chave: a falha cara não é a etiqueta que não sai, mas a que não sai e ninguém se apercebe. Um conector sério distingue o erro de dados (mostra-o e não repete) do erro da transportadora (coloca-o em fila, repete com espera crescente e escreve-o no chatter).
O que é preciso antes
- Contrato e credenciais do ambiente correto. A Correos Express separa teste (
www.test.cexpr.es) e produção (www.cexpr.es); a MRW usa o serviço web Sagec com franquia, assinante, departamento, utilizador e palavra-passe. Ambos trazem um botão de teste de ligação (action_cex_test_connectioneaction_mrw_test_connection) para o verificar antes do primeiro envio real. - Morada normalizada. Nome, rua, localidade, código postal de cinco dígitos em Espanha e telefone com pelo menos nove dígitos, no remetente e no destinatário: a lista literal de
_cex_validate_shipment_inputs. - Peso e volumes na guia. Os módulos leem os pacotes (
package_level_ids/package_ids) ou, se não existirem, um volume comshipping_weightouweight. Peso zero não sai. - Tipo de operação com «Imprimir etiqueta». No Odoo 19, a chamada automática ao validar só ocorre com
print_labelativado. É a causa mais comum de «validei e não aconteceu nada».
O fluxo passo a passo, com o modelo do Odoo em cada passo
- Validar (
stock.picking._action_done). O Odoo 19 chama_send_confirmation_email, questock_deliveryreescreve: com transportadorarate_and_ship, ainda sem tracking e um tipo de operação que imprime etiqueta, executasend_to_shipper()antes de compor o e-mail. - Chamar a API (
delivery.carrier.send_shipping). O Odoo encaminha paracex_send_shippingoumrw_send_shipping: JSON contraapiRestGrabacionEnviok8s/jsonna Correos Express, SOAPTransmEnviocontrasagec.mrw.esna MRW. Se já existia número de envio, devolve-se o existente. - Guardar a etiqueta (
ir.attachment). O PDF é anexado à guia comoEtiqueta_CEX_<número>.pdfouEtiqueta_MRW_<número>.pdfe publicado no chatter. Com vários volumes, a Correos Express devolve várias etiquetas com sufixo_01,_02… - Escrever o tracking (
carrier_tracking_ref).send_to_shippertomatracking_numberda resposta, escreve-o no campo padrão e publica «Paquete enviado al transportista … con número de rastreo …». Os módulos guardam também o seu número próprio. - Avisar o cliente (
mail.template/sms.template).stockenvia «Shipping: Send by Email» se a empresa tiver ativada a confirmação por e-mail, estock_smso SMS. Ambos incluem o tracking apenas secarrier_tracking_refjá estiver preenchido.

Validar antes de chamar: o que se verifica e o que devolve a transportadora se não
A transportadora valida, mas tarde e com mensagens para a sua equipa. Os módulos verificam primeiro no Odoo e só chamam se não houver erros; se os houver, um único UserError com todos. Se mesmo assim rejeitar, a resposta é classificada por palavras-chave e traduzida numa frase para o operador; o administrador vê o detalhe técnico.
| Verificação no Odoo | Se a transportadora a rejeitar na mesma | O que vê o operador |
|---|---|---|
| Morada, localidade, código postal de 5 dígitos (ES), telefone ≥ 9 dígitos | Resposta com «dirección», «código postal», «teléfono», «destinatario», «población» ou «país» | «CEX detectó errores de dirección/CP/teléfono en remitente o destinatario» |
| Peso superior a zero, pelo menos um volume, máximo 99 (CEX) | Resposta com «peso», «kilos», «bulto», «volumen», «alto», «largo», «ancho» | «CEX rechazó peso o datos de bultos» / «MRW rechaza el peso del envío para el servicio seleccionado» |
| Serviço coerente com o destino: internacional (90/91) não para Espanha, PAQ Empresa (92) só para empresas | Código de serviço não contratado ou inválido | A MRW repete com os códigos alternativos do preset e do catálogo; se nenhum entrar, o administrador vê «Servicios probados» no erro |
| Códigos de cliente e requerente presentes | «unauthorized», «forbidden», «credenciales» | «CEX rechazó las credenciales del transportista». Não se repete: não é transitório |
Novas tentativas: uma falha silenciosa é pior do que uma visível
Um 503 em plena preparação de encomendas não é raro. Deixar a guia a meio é a pior resposta; engolir o erro, a segunda. Os módulos fazem uma terceira: decidir se a falha é transitória e repetir com espera crescente.
- Transitório na Correos Express é HTTP 408, 409, 423, 425, 429, 500, 502, 503 ou 504, ou uma mensagem com «timeout», «vuelva a intentarlo», «service unavailable» ou «error interno»; a MRW usa uma lista mais curta: 408, 429, 500, 502, 503 e 504. O resto é erro de dados: é marcado e mostrado.
- Na guia ficam
cex_retry_pending,cex_retry_count,cex_retry_next_attempt,cex_last_error_messageecex_last_attempt_at(na MRW, prefixomrw_), e no chatter «CEX temporalmente no disponible. Reintento automático #1 programado para …». - Uma ação agendada a cada 5 minutos recolhe os pendentes sem número de envio com a hora cumprida, de 50 em 50, e passa-os pelo mesmo código da primeira tentativa.
- Espera: 5, 15, 30, 60, 120 e 240 minutos na Correos Express; 5, 15, 30, 60, 180 e 360 na MRW. Seis tentativas por defeito, configurável. Ao esgotá-las, «Se alcanzó el máximo de reintentos automáticos»: aí é preciso uma pessoa.
- Quem se apercebe: o operador, no erro e no chatter. O Odoo 19 acrescenta a sua rede: se num lote já se processou uma guia na transportadora, o erro seguinte não reverte o lote; converte-se numa atividade de aviso.
O fragmento que fixa a espera, no módulo da Correos Express:
# flexigobe_correos_express/models/delivery_carrier.py (v19.0.3.0.19)
CEX_RETRY_BACKOFF_MINUTES = [5, 15, 30, 60, 120, 240]
def _cex_retry_delay_minutes(self, attempt_no):
self.ensure_one()
idx = max(int(attempt_no or 1) - 1, 0)
if idx >= len(CEX_RETRY_BACKOFF_MINUTES):
idx = len(CEX_RETRY_BACKOFF_MINUTES) - 1
return CEX_RETRY_BACKOFF_MINUTES[idx]O e-mail ao cliente: quando se dispara e o que leva
Dispara-se ao validar, não ao criar a guia. O modelo padrão («Shipping: Send by Email», em Inventário → Definições → Confirmação por e-mail) diz «Nos alegra informarle de que su pedido ha sido enviado» e, se existir carrier_tracking_ref, acrescenta a referência com ligação para carrier_tracking_url; o SMS de stock_sms acrescenta o número de encomenda (object.origin) e a referência em texto simples, sem ligação. Como stock_delivery chama send_to_shipper antes de super()._send_confirmation_email(), o tracking já existe ao compor o e-mail. Se o envio ficou em fila de repetição, o e-mail sai sem tracking.
A ligação é construída por cada módulo: https://s.correosexpress.com/SeguimientoSinCP/search?n=<tracking> na Correos Express e https://www.mrw.es/seguimiento_envios/MRW_historico_nacional.asp?enviament=<número> na MRW. Tracking sem ligação significa que ainda não há referência.
Caso: os dois módulos próprios e em que diferem
Partilham arquitetura e são mantidos para o Odoo 19, 18 e 17. As API diferem, e nota-se na etiqueta, na anulação e no que não fazem.
| Aspeto | Correos Express (v19.0.3.0.19) | MRW (v19 · 1.0.1) |
|---|---|---|
| Protocolo | REST JSON: gravação, etiqueta, seguimento, recolhas, PUDO, parar entrega | SOAP Sagec: TransmEnvio, TransmEnvioInternacional, GetEtiquetaEnvio, CancelarEnvio |
| Etiqueta | PDF, ZPL ou EPL; um anexo por volume | PDF ou ZPL por SOAP; se o binário não chegar, é descarregado do URL que a MRW devolve |
| Multivolume | Lista de volumes com peso e medidas, máximo 99 | Um BultoRequest por volume e NumeroBultos |
| Tracking | Ação agendada a cada 30 minutos que escreve estado, descrição e data na guia | Botão que abre o seguimento da MRW; sem sincronização periódica |
| Anulação | «Parar entrega» por API; se o contrato não o permitir, fica como manual e avisa no chatter | CancelarEnvio; se a MRW disser que já não existe, sincroniza o estado local em vez de falhar |
| Recolhas | Gravar, modificar, anular e consultar; pesquisa de pontos PUDO | Só a data de recolha, dentro do pedido de envio |
| Cobrança na entrega | Não: reembolso é enviado vazio | Não: Reembolso vai fixo em «N» |
Nenhum gere hoje a cobrança na entrega, e perguntam-nos muito por isso. Mais em Correos Express no Odoo e MRW no Odoo; se ainda está a escolher, que transportadora se adequa a um ecommerce no Odoo.
Como verificar que funciona
Não com o sandbox: com uma guia real validada e estas quatro evidências, as das capturas.
- Um anexo
Etiqueta_CEX_…pdfouEtiqueta_MRW_…pdfcom código de barras legível. O da MRW olha para o cabeçalho do binário (%PDF-,^XA,<?xml,<html) e, se não for etiqueta imprimível, não a guarda: di-lo no chatter. carrier_tracking_refpreenchido e «Etiqueta OK» com o número de envio.- No chatter: «Paquete enviado al transportista…», «Etiqueta … generada correctamente» com o PDF, e o SMS ou e-mail ao cliente se estiverem ativados.
- Campos de repetição a zero. Se não, o envio não chegou à transportadora embora a guia esteja validada.
Com uma transportadora sem módulo publicado, o mesmo fluxo e outro adaptador: dentro do serviço de logística no Odoo e, para consultoras, como engenharia para consultorias. A regra dos nossos serviços é a mesma: a etiqueta sai da guia, o tracking volta à guia e ninguém copia nada.
Perguntas frequentes
A etiqueta gera-se ao criar a encomenda ou ao validar a guia?
Ao validar: _action_done dispara send_to_shipper se houver transportadora com integração completa, não houver tracking e o tipo de operação tiver «Imprimir etiqueta». Os módulos acrescentam um botão para o lançar manualmente.
Porque saiu o e-mail ao cliente sem número de seguimento?
Porque ao compô-lo carrier_tracking_ref estava vazio: a transportadora falhou e o envio ficou em fila, ou o tipo de operação não chama a transportadora ao validar. O chatter diz qual.
Pode anular-se um envio a partir do Odoo?
Com ressalvas: a MRW chama CancelarEnvio; a Correos Express usa «Parar entrega» e, se o contrato não a tiver, regista a anulação como manual. Fica no chatter.
Ligações úteis dentro da FlexigoTech
O que fazemos sobre isto
O seu armazém continua a imprimir etiquetas a partir do portal da transportadora?
Diga-nos que transportadora usa, que versão do Odoo tem e quantas guias saem por dia. Dizemos-lhe que parte já existe, o que é preciso configurar e o que teria de ser programado. Escreva para comercial@flexigobe.com ou ligue para +34 616 809 504.

