DataFirefly Odoo Connector: guia de instalação e configuração
Ligue o Shopware 6.6 / 6.7 ao Odoo 12 a 18 através de XML-RPC nativo. Instalação, configuração da chave de API, direções de sincronização, tarefas agendadas e resolução de problemas.
Este guia cobre a instalação, a configuração e a exploração da extensão DataFirefly Odoo Connector para Shopware 6.6 e 6.7. No fim, a sua loja sincronizará produtos, stock, clientes e encomendas com a sua instância Odoo através de XML-RPC nativo, sem qualquer dependência externa nem custo adicional de API de terceiros.
Apresentação
A extensão estabelece uma ponte bidirecional entre o Shopware e o Odoo falando diretamente o protocolo XML-RPC do Odoo (estável desde a versão 8). Sem módulos a instalar do lado do Odoo, sem middleware pago, sem SaaS intermediário.
| Entidade | Odoo → Shopware (pull) | Shopware → Odoo (push) |
|---|---|---|
| Produtos (product.template) | ✅ | ✅ |
| Stock (qty_available / free_qty) | ✅ | — |
| Categorias (product.category) | ✅ | ✅ |
| Clientes (res.partner) | — | ✅ com moradas filhas |
| Encomendas (sale.order) | — | ✅ com confirmação e fatura opcionais |
Pré-requisitos
- Shopware 6.6.x ou 6.7.x (todas as versões menores).
- PHP 8.2, 8.3 ou 8.4.
- Extensões PHP: curl, xml, simplexml (presentes por predefinição na quase totalidade dos alojamentos).
- Odoo 12, 13, 14, 15, 16, 17 ou 18, em Community ou Enterprise. O Odoo.sh, o Odoo Online (SaaS) e as instâncias auto-alojadas funcionam de forma idêntica.
- Um utilizador Odoo dedicado à API (recomendado) com direitos de leitura e escrita nos modelos usados (product.template, product.product, res.partner, sale.order, stock.warehouse, product.category, res.country, account.tax).
Instalação
Por carregamento na administração
- Transfira o arquivo
DfOdooConnector-v1.0.0.zipa partir da sua conta de cliente. - Na administração do Shopware: Extensões → As minhas extensões → Carregar uma extensão.
- Selecione o ZIP e clique em Instalar.
- Ative a extensão clicando no interruptor.
Por consola SSH
cd /caminho/para/shopware
cp DfOdooConnector-v1.0.0.zip custom/plugins/
cd custom/plugins && unzip DfOdooConnector-v1.0.0.zip
sudo -u www-data setsid php bin/console plugin:refresh
sudo -u www-data setsid php bin/console plugin:install --activate DfOdooConnector
sudo -u www-data setsid php bin/console cache:clear
Recompilação da administração para carregar o módulo em Vue 3:
sudo -u www-data setsid php bin/build-administration.sh
df_odoo_mapping (correspondências persistentes Shopware ↔ Odoo) e df_odoo_log (registo das operações). Nenhuma tabela existente é alterada.
Configuração do lado do Odoo
Criar um utilizador dedicado
É fortemente recomendado criar um utilizador Odoo dedicado à integração em vez de usar uma conta de administrador pessoal. Isso permite auditar com precisão as ações do conector e revogar o seu acesso de forma independente.
- No Odoo: Definições → Utilizadores e empresas → Utilizadores.
- Crie um utilizador chamado, por exemplo,
Shopware Bridge. - Dê-lhe os direitos necessários: Inventário (utilizador), Vendas (administrador dos documentos), Faturação (utilizador se ativar a criação de fatura), Contactos (utilizador).
Gerar uma chave de API
- Inicie sessão no Odoo com esse novo utilizador.
- Clique no avatar no canto superior direito → Preferências.
- Separador Conta → Chaves de API → Nova chave de API.
- Dê-lhe um nome descritivo (por exemplo
Shopware Connector) e copie o valor gerado.
Configuração do lado do Shopware
Preencher a ligação
Na administração do Shopware: Definições → Sistema → Extensões → Df Odoo → Definições, ou diretamente pelo menu lateral Definições → Df Odoo → Definições.
- URL do Odoo: URL completo da sua instância sem barra final, por exemplo
https://aminhaconta.odoo.com. - Nome da base de dados: visível no URL do Odoo depois de
?db=, ou em Definições → Técnico → Base de dados. - Utilizador: login do utilizador dedicado, geralmente o seu endereço de email.
- Chave de API do Odoo: valor copiado no passo anterior.
- Tempo de espera: 30 segundos por predefinição, suficiente na maioria dos casos.
Testar a ligação
Clique no botão Testar a ligação no canto superior direito. Se estiver tudo correto, uma notificação verde mostra a versão do Odoo e o identificador do utilizador (uid). Se a ligação falhar, a mensagem de erro devolvida pelo Odoo é apresentada tal como está.
curl -X POST -H "Authorization: Bearer ADMIN_TOKEN" https://oseushopware.com/api/_action/df-odoo/test-connection
Direções de sincronização
Cada entidade tem um seletor independente: desativado, Odoo → Shopware (pull), Shopware → Odoo (push), ou bidirecional. Os valores predefinidos são:
- Produtos: bidirecional
- Stock: Odoo → Shopware (o Odoo é a fonte de verdade)
- Clientes: Shopware → Odoo
- Encomendas: Shopware → Odoo
- Categorias: desativado (a ativar manualmente consoante a sua organização)
Sincronização dos produtos
Estratégias de correspondência
São configuráveis três estratégias:
- SKU (recomendada):
productNumberdo Shopware ↔default_codedo Odoo. - ID do Odoo: assenta apenas na tabela de mapeamento persistente. Útil se os seus SKU forem voláteis.
- Código de barras (EAN):
eando Shopware ↔barcodedo Odoo. Exige EAN preenchidos dos dois lados.
Uma vez ligados, dois produtos mantêm-se emparelhados através da tabela df_odoo_mapping, mesmo que o SKU mude depois.
Pull a partir do Odoo
A tarefa agendada lê os product.template alterados desde a última execução (campo write_date) e cria ou atualiza os produtos correspondentes do lado do Shopware. Os campos sincronizados são: nome, SKU, preço de venda, preço de custo, descrição curta, descrição longa, peso, volume, estado ativo, categoria, impostos.
Push para o Odoo
Os produtos principais do Shopware (com parentId = null) ativos são enviados para o Odoo como product.template do tipo product (artigo armazenável). As variantes do Shopware são enviadas sob o seu produto principal.
skipped. Isto evita saturar o Odoo nos crons sucessivos.
Sincronização do stock
O stock é sempre puxado do Odoo (nunca o contrário). A cada 15 minutos, a tarefa agendada lê as variantes product.product em lotes de 100 por identificador de template principal, agrega qty_available ou free_qty (configurável globalmente) e atualiza depois o campo stock de cada produto Shopware numa única consulta DAL.
qty_available reflete o stock físico presente em armazém. O free_qty retira as quantidades já reservadas em encomendas não entregues. O free_qty é geralmente preferível num site de venda, porque evita a sobrevenda.
Sincronização das categorias
Desativada por predefinição. Ative-a se a sua árvore de categorias tiver de se manter sincronizada com a do Odoo. A hierarquia parent_id é preservada dos dois lados. Tal como nos produtos, um hash de conteúdo evita as escritas desnecessárias.
Sincronização dos clientes
Os clientes do Shopware são enviados como res.partner do Odoo com:
- Desduplicação por email: antes de qualquer criação, é procurado um parceiro existente com o mesmo email e
parent_id = false. Se existir, é atualizado em vez de duplicado. - company_type: company se o campo empresa da morada de facturação estiver preenchido, person caso contrário.
- Moradas filhas: a morada de facturação predefinida é criada como parceiro filho com
type='invoice', e a morada de entrega como parceiro filho comtype='delivery'. - Número de IVA intracomunitário: transposto para o campo
vatdo parceiro principal. - País e região: resolvidos por código ISO com cache em memória dentro do pedido.
Sincronização das encomendas
Em tempo real no checkout
Se a opção Enviar cada encomenda logo na validação estiver ativa, um event subscriber escuta o CheckoutOrderPlacedEvent e envia de imediato a encomenda para o Odoo depois da finalização do checkout. O cliente é criado no Odoo se for necessário (através da sincronização de clientes), e a encomenda é depois criada como sale.order com:
partner_idresolvido através do mapeamento de clientes.order_lineem sintaxe de tuplo do Odoo:[0, 0, {name, product_uom_qty, price_unit, product_id}].- Uma linha adicional para os portes se o
totalPricedo shipping for superior a zero. company_id,warehouse_id,pricelist_idsegundo os valores predefinidos configurados.
df_odoo_log e a encomenda será retomada nos 10 minutos seguintes pela tarefa agendada df_odoo.order_sync, que percorre as encomendas dos últimos 7 dias ainda não mapeadas.
Filtro de estado
O filtro Estado das encomendas permite restringir as encomendas enviadas:
- Todas: qualquer encomenda validada é enviada (recomendado em B2C com pagamento imediato).
- Apenas pagas: só as encomendas cujo estado de pagamento é paid são enviadas. Evita enviar carrinhos abandonados com pagamento manual.
- Pagas ou expedidas: acrescenta às anteriores as encomendas expedidas antes do pagamento (B2B com prazos).
Confirmação e fatura automáticas
Duas opções controlam o que acontece do lado do Odoo depois de a encomenda ser criada:
- Confirmar a encomenda: chama
action_confirmnasale.order, que passa então diretamente ao estado encomenda confirmada em vez de ficar como orçamento. - Criar a fatura: chama
_create_invoicespara gerar de imediato uma fatura validada. O identificador da fatura criada é memorizado como mapeamento do tipoinvoice.
Multi sales channel
Todos os parâmetros da extensão podem ser substituídos por canal de venda. No topo da página Definições, o seletor nativo do Shopware permite alternar entre Todos os canais e um canal específico.
Casos de uso típicos:
- Um canal B2C que envia para um Odoo principal e um canal B2B que envia para um Odoo distinto.
- Um canal de produção com direção push e um canal de staging com direção desativada.
- Diferentes identificadores Odoo (warehouse, sales team, pricelist) consoante o canal.
Tarefas agendadas
| Nome interno | Frequência | Ação |
|---|---|---|
df_odoo.product_sync |
1 hora | Pull e depois push de produtos segundo a direção configurada. O pull só examina as fichas alteradas desde -2 h. |
df_odoo.stock_sync |
15 minutos | Pull do stock a partir do Odoo para todos os produtos já mapeados. |
df_odoo.customer_sync |
1 hora | Push dos clientes ativos ainda não mapeados (100 no máximo por execução). |
df_odoo.order_sync |
10 minutos | Push das encomendas dos últimos 7 dias ainda não mapeadas (50 no máximo por execução). |
Forçar a execução de uma tarefa a partir da consola:
sudo -u www-data setsid php bin/console scheduled-task:run-single df_odoo.product_sync
messenger:consume ou tarefa systemd). Verifique em Definições → Sistema → Fila de mensagens que a scheduled_task é consumida regularmente.
Módulo de administração
Aparece uma secção Df Odoo em Definições → Extensões com quatro páginas.
Painel
Contadores em direto (mapeamentos ativos por entidade, atividade das últimas 24 h por estado), botões de sincronização manual por entidade (pull e push), faixa de estado da ligação, lista dos erros recentes e atalhos para as outras páginas.
Definições
Formulário completo com seletor de canal de venda. Botões Testar a ligação e Guardar na barra de ações.
Registo
Todas as operações ficam registadas em df_odoo_log com o seu estado (success, error, warning, skipped), a sua direção, a entidade em causa, a duração em milissegundos e a mensagem completa. Filtros combináveis por estado, tipo de entidade e direção. Paginação do lado do servidor.
Correspondências
Vista de leitura sobre a tabela df_odoo_mapping com pesquisa, filtro por tipo de entidade e ordenação por data da última sincronização. Prática para verificar se um dado produto está mesmo mapeado ao ID Odoo esperado.
API REST de administração
Todos os endpoints exigem autenticação normal de administração (Bearer token).
| Método | Endpoint | Parâmetros |
|---|---|---|
| POST | /api/_action/df-odoo/test-connection |
salesChannelId (opcional) |
| POST | /api/_action/df-odoo/sync/products |
direction=pull|push, salesChannelId |
| POST | /api/_action/df-odoo/sync/stock |
salesChannelId |
| POST | /api/_action/df-odoo/sync/customers |
salesChannelId |
| POST | /api/_action/df-odoo/sync/orders |
salesChannelId, limit (1-500) |
| POST | /api/_action/df-odoo/sync/categories |
direction=pull|push |
| GET | /api/_action/df-odoo/stats |
— |
| GET | /api/_action/df-odoo/logs |
status, entityType, direction, page, perPage |
Exemplo de chamada para forçar um push de produtos:
curl -X POST
-H "Authorization: Bearer ADMIN_TOKEN"
-d "direction=push"
https://oseushopware.com/api/_action/df-odoo/sync/products
Tabelas e dados guardados
A extensão cria duas tabelas MySQL:
df_odoo_mapping: correspondências persistentes (identificador Shopware ↔ identificador Odoo) com hash de sincronização e payload opcional. Uma linha é única no par (tipo de entidade, identificador Shopware) e no par (tipo de entidade, identificador Odoo).df_odoo_log: registo das operações com estado, duração, mensagem, payload e identificador do canal de venda.
Nenhuma tabela normal do Shopware é alterada.
Desinstalação
A partir da administração: Extensões → As minhas extensões → Df Odoo → Desinstalar.
Uma caixa de diálogo propõe duas opções:
- Conservar os dados do utilizador marcado: as tabelas
df_odoo_mappingedf_odoo_logsão preservadas, bem como os parâmetros de sistema. Prático em caso de reinstalação posterior. - Conservar os dados do utilizador desmarcado: as duas tabelas são eliminadas (DROP TABLE) na desinstalação. A instância Odoo nunca é tocada.
Resolução de problemas
«Configuração Odoo incompleta» no teste de ligação
Um dos quatro campos obrigatórios (URL, base de dados, utilizador, chave de API) está vazio. Verifique que selecionou mesmo o canal de venda certo antes de guardar.
«401 Unauthorized» ou «access denied»
A chave de API foi revogada do lado do Odoo, ou o utilizador não tem os direitos necessários no modelo visado. Regenere uma chave de API e verifique os direitos Odoo do utilizador (nomeadamente Inventário → Utilizador e Vendas → Administrador dos documentos).
«Ligação recusada» ou timeout
O URL do Odoo não está acessível a partir do servidor Shopware. Verifique que a firewall permite ligações de saída HTTPS para o domínio do Odoo. Aumente o tempo de espera se a sua instância Odoo for lenta a responder.
Os produtos não se sincronizam
Verifique o registo (página Registo) à procura de entradas em erro. Ative o modo de depuração para registar também as operações skipped e perceber se o hash de conteúdo faz com que nada mude realmente.
As encomendas não saem no checkout
Verifique que a opção Enviar cada encomenda logo na validação está marcada e que a direção Encomendas está em Shopware → Odoo. Se o filtro de estado estiver em Apenas pagas e o pagamento for assíncrono, é a tarefa agendada que envia a encomenda alguns minutos depois do recebimento.
Limites conhecidos
- Os atributos de variantes do Odoo (
product.attribute) ainda não são mapeados automaticamente. As variantes do Shopware são enviadas como produtos principais do Odoo (product.template). As variantes Odoo criadas manualmente mantêm-se corretamente ligadas através do seu template principal. Está prevista uma gestão nativa na versão 1.1. - Os descontos de linha de encomenda são transpostos como
price_unitajustado, e não comodiscountdo Odoo. - Os métodos de pagamento e de expedição do Shopware não são mapeados para os
journal_iddo Odoo: são usados os valores predefinidos do Odoo.
Suporte
Para qualquer questão, contacte a equipa DataFirefly através do formulário de contacto em datafirefly.com. Lembre-se de juntar a exportação do registo (página Registo → botão de exportação em breve) ou, no mínimo, uma captura da linha em erro, bem como a versão exata do Shopware, do PHP e do Odoo.