Instalação
Requisitos
Magento 2.4.x — testado na 2.4.9, compatível com versões 2.4.* anteriores. PHP 8.1–8.5. Requer o codingrow/module-core (instalado automaticamente como dependência do Composer) para o menu de administração partilhado da Codingrow e a validação da licença.
Passos de configuração
- Adicione as credenciais que irá receber por email ao
auth.jsonna raiz do seu projeto Magento:{ "http-basic": { "repo.codingrow.com": { "username": "...", "password": "..." } } } composer config repositories.codingrow composer https://repo.codingrow.comcomposer require codingrow/module-oetibin/magento module:enable Codingrow_Oetibin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush- Cole a sua chave de licença em Admin → Stores → Configuration → Codingrow → Order Export & Tracking Import → License → Chave de licença, guarde e depois
bin/magento cache:flush. - No grupo Geral dessa mesma secção, defina Habilitar módulo como "Yes" — o módulo é distribuído ativado ao nível do Magento, mas funcionalmente desligado, pelo que nunca exporta nada até o ativar explicitamente.
- Crie o seu primeiro perfil em Codingrow → Order Export & Tracking Import → Export Profiles — veja Perfis abaixo.
Todo o admin de perfis, o construtor de mapeamento, o registo e cada e-mail de notificação estão disponíveis em 7 idiomas, selecionados automaticamente de acordo com o idioma do utilizador admin:
Configuração admin
A configuração está em Stores → Configuration → Codingrow Extensions → Order Export & Tracking Import (Licença mais as definições de export/tracking). Os perfis de export e o seu mapeamento / condições de disparo são geridos na grelha Order Export dedicada.
Desinstalação
composer remove codingrow/module-oeti e depois
bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush.
Os perfis e o registo de exportação/rastreio (codingrow_oeti_profile,
codingrow_oeti_log, codingrow_oeti_tracking_log) nunca são eliminados automaticamente —
use primeiro Exportar perfil se quiser manter uma cópia
da configuração do seu perfil.
Guia de utilizador
Perfis
Tudo no módulo está organizado em torno de perfis, listados em Codingrow → Order Export & Tracking Import → Export Profiles. Cada perfil é completamente independente: o seu próprio nome, o seu próprio interruptor de ativado/desativado, o(s) seu(s) próprio(s) estado(s) de acionamento, o seu próprio destino (canal + formato), o seu próprio mapeamento de campos e a sua própria linha no registo de exportação — pode executar quantos perfis quiser lado a lado (um por fornecedor, um por transportadora, um para um ERP interno), e desativar ou eliminar um nunca afeta os outros.
Um perfil desativado (Perfil habilitado = "No") nunca exporta nada, quer seja acionado automaticamente, pela ação manual, ou pelo comando CLI — isto é independente do interruptor global Habilitar módulo em System Config, que atua como um único interruptor mestre que desliga todos os perfis de uma só vez.
Canais & formatos
Cada perfil escolhe um canal (onde o payload é entregue) e um formato (como é serializado) — as duas escolhas são independentes, pelo que qualquer formato funciona com qualquer canal.
| Canal | Utilização típica | Definições principais |
|---|---|---|
| REST API | Envia o payload como um pedido HTTP a um webservice | URL de destino, método HTTP (GET/POST/PUT/PATCH), autenticação (Nenhuma, HTTP Basic, Bearer token), segundos mínimos entre pedidos (limitação de taxa, 1 segundo por defeito) |
| FTP / SFTP | Carrega o payload como um ficheiro para um servidor remoto | Anfitrião, porta (21 por defeito), nome de utilizador, palavra-passe, caminho remoto, FTPS opcional (TLS explícito), modo passivo |
| Ficheiro local | Escreve o payload num ficheiro dentro da
própria pasta pub/media/ desta loja, para um sistema externo o recolher via HTTP |
Subpasta — o ficheiro fica em
pub/media/codingrow_oeti/<subfolder>/ (subpasta por defeito:
"default") |
Formatos: JSON, XML ou CSV, escolhidos de forma independente do canal acima — o mesmo mapeamento de campos (ver abaixo) alimenta os três, o formato apenas muda a forma como é serializado.
Mapeamento de campos
O separador Mapping é uma tabela de linhas, cada uma ligando um destino (o
nome do campo na saída — um ponto significa um nível de aninhamento, ex.:
customer.email) a um caminho de origem escolhido numa lista pendente
com todos os campos disponíveis da encomenda/cliente/item. As linhas vazias são ignoradas ao
guardar.
As linhas são lidas de cima para baixo na mesma forma da própria saída: primeiro um modelo de Cabeçalho opcional, depois as linhas de mapeamento ao nível da encomenda, depois quaisquer Blocos de repetição (ver abaixo), e por fim um modelo de Rodapé opcional.
Transformações
Cada linha de mapeamento pode aplicar uma transformação ao valor de origem antes de este ser escrito no campo de destino:
| Transformação | O que faz |
|---|---|
| Nenhuma | Cópia direta do valor do caminho de origem (recorre ao "Valor predefinido" quando a origem está vazia). |
| Valor estático | Ignora completamente a origem, escreve sempre o texto fixo em "Valor". |
| Remover tags HTML | Remove a formatação HTML do valor de origem — útil para um nome ou descrição de produto que traga formatação residual. |
| Modelo de texto | Texto livre com placeholders, ex.:
{order.shipping_address.firstname} {order.shipping_address.lastname}.
Também está disponível uma função dentro de um placeholder:
striphtml{path} (igual à transformação Remover tags HTML, utilizável em linha) e
substr{path,N} (remove os primeiros N caracteres, ex.:
substr{order.some_code,3}). |
| Buscar e substituir | Procura o texto de "Procurar" dentro do valor de origem (sem distinguir maiúsculas/minúsculas) e substitui-o por "Valor" exatamente como indicado. |
| Número | Serializa o valor como um número JSON real em vez
de uma string entre aspas — use-a quando o destino valida rigorosamente o TIPO do
campo (uma quantidade enviada como a string em bruto da base de dados
"1.0000" é rejeitada por algumas APIs, enquanto 1.0 como número
real é aceite). Isto não é o comportamento predefinido para campos com
aspeto numérico de propósito: ativá-la em todo o lado removeria silenciosamente zeros à
esquerda de coisas como um código postal ou um código de artigo, pelo que é uma escolha
opcional por linha, não um comportamento automático. |
A mesma sintaxe {path} / striphtml{} / substr{}
usada nas linhas Modelo de texto também está disponível nas linhas dos Blocos de repetição e
no Cabeçalho/Rodapé opcional do perfil.
Blocos de repetição
Um bloco de repetição constrói um array aninhado na saída — o caso mais comum é uma entrada por item da encomenda. Cada bloco tem uma chave de saída do bloco (onde o array é escrito na saída) e uma coleção de origem (sobre o que repete, ex.: os itens da encomenda), mais o seu próprio conjunto de linhas de mapeamento por baixo, avaliadas uma vez por elemento com o "atual" delimitado a esse elemento — pelo que o caminho de origem de uma linha dentro de um bloco de repetição se refere aos campos do item atual, não à encomenda como um todo.
items, coleção de origem
"Itens da encomenda", e duas linhas (sku ← SKU do item atual, qty ←
quantidade do item atual) produz:
{
"items": [
{ "sku": "43241", "qty": 2 }
]
}
Um perfil pode definir qualquer número de blocos de repetição independentes — por exemplo,
um para a lista de itens e outro separado para uma lista de descontos aplicados.
Condições de disparo
O separador Geral tem um construtor de condições AND/OR aninhadas — a mesma interface em
árvore utilizada pelas Cart Price Rules do próprio Magento (um link "Add" em cada grupo para
adicionar uma condição ou um subgrupo aninhado, um ícone de remoção em qualquer nó) — que decide
tanto quais as linhas da encomenda que um perfil realmente exporta
como se o perfil exporta a encomenda de todo. Cada condição compara um atributo
de produto (por exemplo, sku, um atributo personalizado "código do fornecedor",
price...) com um valor, com um operador: igual a/diferente de, contém/não contém,
começa por/termina em, maior que/menor que (ou igual a), está vazio/não está vazio.
As condições dentro de um grupo combinam-se com TODAS (AND) ou QUALQUER (OR), e os grupos
podem aninhar-se dentro de grupos — por exemplo, sku contém "ABC" OR (supplier_code =
"Supplier2" AND price > 10). Nenhuma condição configurada = sem filtro, todas as
linhas são exportadas (o mesmo que o antigo "Somente itens do fornecedor" = "No" antes da
versão 1.3.0).
Utilização típica com vários fornecedores em dropshipping: um perfil por
fornecedor, cada um com a sua própria condição (por exemplo, Perfil A: supplier_code =
"Supplier1", Perfil B: supplier_code = "Supplier2") — uma encomenda que
contenha itens de ambos os fornecedores aciona corretamente os dois perfis em paralelo, cada um
exportando apenas as linhas que lhe pertencem. Se nenhuma linha corresponder às condições de um
determinado perfil, esse perfil simplesmente não exporta essa encomenda (ver o estado
"Ignorado" do registo abaixo) — não é um erro.
Cada atributo utilizado numa condição fica automaticamente disponível como campo mapeável no
payload (items.attributes.<code>, ver Mapeamento de campos acima). Quando as
condições excluem linhas de uma encomenda, a pré-visualização em tempo
real mostra um aviso explícito a indicar quantas linhas ficaram de fora e porquê — para que
um payload vazio ou mais curto do que o esperado nunca seja uma surpresa silenciosa.
Pré-visualização em tempo real
O botão Preview na página de edição do perfil constrói um perfil temporário, nunca guardado, a partir do que está atualmente no formulário — incluindo alterações que ainda não guardou — e executa-o sobre uma encomenda real que escolher, através exatamente do mesmo caminho de código usado numa exportação genuína. O resultado é o payload literal em JSON/XML/CSV que essa encomenda produziria, para que possa corrigir o mapeamento antes sequer de ativar o perfil, em vez de o descobrir através de uma exportação real falhada.
Acionamento & deduplicação
A lista de seleção múltipla Status de disparo no separador Geral indica qual(is) o(s) estado(s) da encomenda que inicia(m) uma exportação automática para esse perfil (Ctrl/Cmd+clique para selecionar mais do que um) — só é verificada no acionamento automático, orientado por eventos; a ação manual na grelha e o comando CLI ignoram-na de propósito, uma vez que acionar manualmente já é, em si, a escolha deliberada de exportar independentemente do estado. A ação manual "Export via Codingrow Order Export" na grelha Sales > Orders executa, com um clique, todos os perfis ativos sobre as encomendas selecionadas — as próprias condições de disparo de cada perfil decidem o que ele realmente envia, exatamente como no acionamento automático.
Cada tentativa é escrita no registo desse perfil (ver abaixo), e o registo é também o que evita duplicados: a mesma encomenda nunca é exportada duas vezes automaticamente pelo mesmo perfil, seja o que for que aconteça depois à encomenda (mais edições, mudanças de estado para trás e para a frente). Se for necessário um reenvio genuíno — depois de resolver um problema do lado do destino, por exemplo — use o Forçar reenvio, que ignora explicitamente esta proteção.
Importação de rastreio
Um separador Tracking Import por perfil (desativado por defeito) executa uma consulta automática por encomenda — redesenhada na v1.5.0. Cada encomenda que este perfil exportou com sucesso, que ainda tem itens por enviar e que não tem mais de 45 dias, é consultada individualmente sobre o seu próprio estado de envio; para os itens reportados como enviados cria uma remessa nativa do Magento com o respetivo número de rastreio, reutilizando as próprias Condições de disparo do perfil para saber quais os itens da encomenda que lhe pertencem. Não existe qualquer janela de datas em lote — o modelo é estritamente um pedido por cada encomenda em aberto em cada ciclo.
Uma encomenda ainda não totalmente enviada após 45 dias sai do ciclo automático: é escrita uma única vez no registo com o estado Timeout (mais um e-mail eventual), pelo que nunca fica a consultar o fornecedor indefinidamente.
Request. A metade superior do separador define a chamada de saída:
| Campo | Significado |
|---|---|
| Check endpoint URL | URL de base do endpoint de estado do fornecedor, sem qualquer query string. |
| HTTP method | GET ou POST. |
| Poll frequency (minutes) | Com que frequência corre o cron deste perfil. |
| Minimum seconds between requests | Limite de taxa entre as chamadas individuais por encomenda dentro de um mesmo ciclo (por defeito 1s; 0 = sem limite). |
| Different authentication than the profile | Se Não (por defeito) a verificação reutiliza as credenciais do canal do próprio perfil; em Sim o endpoint de rastreio tem a sua própria autenticação. |
| Request parameters | Uma grelha de linhas Name + Type + Value, uma por cada parâmetro enviado ao endpoint (ver os cinco tipos de parâmetro abaixo). |
| Request preview (JSON) | Pré-visualização em direto da chamada exata; o botão Send test request ao lado dispara uma chamada HTTP real, e colar um exemplo de pedido na pré-visualização reconstrói as linhas de parâmetros a partir dele. |
Cada linha de Request parameters escolhe um de cinco Type de valor:
| Type | Valor enviado |
|---|---|
| Fixed value | O texto literal introduzido em Value. |
| Today | A data de hoje (Y-m-d). |
| Order export date | A data em que essa encomenda foi exportada. |
| Mapped export field | O valor que a exportação calculou para um target escolhido dessa encomenda — por exemplo, a referência da encomenda no fornecedor. |
| Template | Texto livre com a função date{N} (hoje ±N dias),
por exemplo date{-7}. |
Response mapping. A metade inferior mapeia a resposta do fornecedor. Nunca escreve os caminhos da resposta à mão: obtenha uma resposta real — com Send test request, ou colando uma resposta capturada no quadro Response sample — e cada lista pendente abaixo é preenchida a partir dos campos efetivamente encontrados nessa resposta.
| Campo | Significado |
|---|---|
| Reference field | Qual o target de Order Export que contém a referência da encomenda (capturada em cada tentativa de exportação, com sucesso ou com falha). |
| Order match field in response | O campo da resposta com que é comparada para identificar a encomenda certa. |
| Tracking number / Tracking URL | Campos da resposta que contêm o número de rastreio e, se existir, o seu link clicável. |
| Carrier code / Carrier name | Campos da resposta que contêm o código da transportadora e a sua etiqueta. |
| Multiple tracking numbers for this shipment | Interruptor para os fornecedores que devolvem mais do que um número de rastreio por remessa; mostra Tracking numbers: collection (o array de entradas de rastreio) e Tracking numbers: value path in each element (onde está o número dentro de cada entrada). |
| Shipped items: collection | O array na resposta que lista os itens enviados. |
| Shipped items: SKU path in each element / Shipped items: quantity path in each element | Onde estão o código do item e a quantidade enviada dentro de cada elemento desse array. |
| Item matching attribute | O atributo de produto com que reconhecer os itens do fornecedor, uma vez que os fornecedores reportam o seu próprio código, não o SKU do Magento. |
Remessas parciais. Se uma encomenda tiver itens de vários fornecedores (ou um fornecedor enviar em mais do que uma vaga), cada verificação só cria remessa para os itens efetivamente reportados como enviados nesse momento, nunca além do que ainda falta enviar — pelo que uma encomenda acabar legitimamente por ter várias remessas ao longo do tempo é o comportamento pretendido, não um erro.
E-mail ao cliente. Quando o fornecedor fornece um link de rastreio clicável (um URL, não apenas um número), o cliente recebe um e-mail com o botão "Rastreie a sua encomenda" em vez do e-mail nativo simples do Magento (que mostraria apenas o número, sem link clicável para uma transportadora que o Magento não reconhece nativamente). Quando o fornecedor não fornece um URL, é utilizado o e-mail nativo padrão, sem alterações.
Migração automática. Os perfis já configurados com a versão anterior são migrados automaticamente na atualização — não é necessária qualquer reconfiguração.
Não é necessária qualquer ação manual em funcionamento normal: as verificações por encomenda correm sozinhas em segundo plano, ao ritmo configurado (o cron do Magento tem de estar em execução, como para qualquer tarefa agendada).
https://codingrow.com/sample-tracking.jsonOpenAPI:
https://codingrow.com/sample-api.openapi.yamlRegisto & reenvio forçado
A partir da versão 1.4.0, o registo deixou de estar dividido por perfil (um separador Log dentro de cada perfil). Uma única página de Registo (botão na grelha Export Profiles) lista encomendas — não tentativas individuais — uma por linha, paginada, com o último estado de exportação e o último estado de rastreio lado a lado: um único relance sobre uma encomenda, mesmo quando estão envolvidos vários perfis/fornecedores.
Ao clicar em Ver histórico completo abre-se o histórico completo dessa encomenda, dividido em duas secções — Registo de exportação e Registo de rastreio — cada uma listando todas as tentativas/verificações de todos os perfis envolvidos, com uma linha de detalhes expansível (payload exato do pedido enviado, corpo da resposta recebida) e, do lado da exportação, um botão de Reenvio forçado por linha.
Do lado da exportação, uma tentativa é Sucesso, Erro ou Ignorado. Ignorado não é um erro: nenhum item da encomenda correspondeu às condições de disparo desse perfil, pelo que nada foi enviado — útil com vários perfis/fornecedores para perceber de relance porque é que um determinado perfil não exportou uma determinada encomenda. Do lado do rastreio, uma verificação falhada normalmente significa apenas que o fornecedor ainda não reportou nada enviado para esses itens; é repetida automaticamente na próxima consulta, sem necessidade de qualquer ação manual.
O Reenvio forçado (apenas do lado da exportação) de uma linha falhada ou ignorada volta a executar a exportação para essa encomenda exata através desse perfil exato, agora mesmo, ignorando a proteção de deduplicação — uma caixa de diálogo de confirmação explica isto antes de executar, uma vez que se trata de uma anulação deliberada, disponível tanto a partir da página principal de Registo como a partir do detalhe da encomenda. O rastreio não tem um equivalente manual de "forçar verificação": a próxima consulta agendada simplesmente tenta novamente.
E-mails de notificação de falhas
Duas definições do separador Geral controlam as notificações de falha, independentemente do registo (que regista sempre cada tentativa, independentemente destas definições): Destinatários da notificação (um ou mais endereços de email, separados por vírgulas — deixe vazio para não enviar nada) e Enviar e-mail para (que eventos desencadeiam uma notificação).
O corpo do e-mail inclui o erro real devolvido pelo destino, não apenas uma linha de estado
HTTP genérica: quando o corpo da resposta é um JSON interpretável com um campo
message, essa mensagem é adicionada literalmente (ex.: "Destination returned HTTP
422 - Minimum product quantity is 1.0"); caso contrário, o corpo da resposta em bruto é
incluído, truncado a 500 caracteres — para que a causa real seja visível diretamente na caixa
de entrada, sem abrir o registo.
Importar / Exportar perfil
O botão Exportar perfil na página de edição de um perfil transfere toda a sua configuração — definições gerais, destino, linhas de mapeamento e blocos de repetição — como um único ficheiro JSON, com as credenciais do destino deliberadamente excluídas para que o ficheiro seja seguro de guardar, partilhar com o suporte, ou incluir junto de um deployment. O botão Importar perfil na grelha Export Profiles recria um perfil a partir de um ficheiro desses — a utilização típica é mover um perfil de uma loja de staging/demonstração para produção, ou manter uma cópia de segurança de um mapeamento com que está satisfeito antes de continuar a experimentar. As credenciais têm sempre de ser reintroduzidas manualmente após uma importação, uma vez que nunca estiveram no ficheiro.
Licença
Uma licença por domínio, introduzida em Admin → Stores → Configuration → Codingrow → Order Export & Tracking Import → License → Chave de licença. Inclui todas as atualizações para esse domínio. Precisa de mudar para um domínio diferente (staging → produção, ou uma migração de site)? A sua primeira alteração de domínio é gratuita e instantânea a partir da sua página de conta — sem esperas, sem necessidade de ticket. A partir da segunda alteração, é permitida uma mudança por ano. Também pode pedir um reembolso dentro de 30 dias após a compra, por si próprio, a partir da mesma página de conta.