# Integração One Beat

# Introdução

Este material explica o funcionamento do módulo **onebeat\_pedidos\_faturados**, que faz parte do sistema ISNAPP. O texto foi escrito em duas camadas: uma linguagem simples para quem usa o dia a dia da operação, e detalhes técnicos para quem gerencia a área de Tecnologia da Informação.

<div class="caixa-simples" id="bkmrk-em-poucas-palavras%3A-">**Em poucas palavras:** este programa pega as informações dos pedidos feitos pelas lojas, verifica o que já foi recebido e o que ainda falta chegar, e envia tudo para uma tabela especial que o sistema **OneBeat** usa para tomar decisões de estoque.</div><div class="caixa-tecnica" id="bkmrk-resumo-t%C3%A9cnico%3A-bibl">**Resumo técnico:** biblioteca PHP (CoreVersion 3) que sincroniza movimentações de pedidos do ERP para a tabela `franquia_1beat` no banco `franquia_osklen_relatorio`, com controle incremental por ponteiro de execução e lock de concorrência em arquivo.</div>## Para quem é esta documentação?

<table id="bkmrk-perfil-o-que-voc%C3%AA-va"><tbody><tr><th>Perfil</th><th>O que você vai encontrar</th></tr><tr><td>Usuário da operação / loja</td><td>Explicações sem termos difíceis sobre o que o sistema faz com os pedidos</td></tr><tr><td>Gestor ou diretor de T.I.</td><td>Arquitetura, bancos de dados, fluxos, instalação e regras de negócio</td></tr><tr><td>Equipe de suporte</td><td>Fluxos de execução, mensagens de erro e glossário</td></tr></tbody></table>

## Arquivos do módulo

<table id="bkmrk-arquivo-fun%C3%A7%C3%A3o-contr"><tbody><tr><th>Arquivo</th><th>Função</th></tr><tr><td>`controle.php`</td><td>Lógica principal: coleta, transforma e grava os pedidos</td></tr><tr><td>`instalador.php`</td><td>Cria o banco e a tabela de destino na primeira instalação</td></tr><tr><td>`visual.html`</td><td>Tela simples de confirmação de carregamento do módulo</td></tr></tbody></table>

![O módulo fica no meio: lê os pedidos do ERP e prepara os dados para o OneBeat.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-i3bkfghd.png)

Figura 1 — O módulo fica no meio: lê os pedidos do ERP e prepara os dados para o OneBeat.

# O que este sistema faz?

Imagine que uma loja da franquia faz um pedido de produtos para a matriz. O pedido é registrado no sistema. Depois, conforme os produtos chegam na loja, o sistema registra o que foi recebido.

Este módulo acompanha essa história e responde três perguntas importantes:

- **1. Quanto foi pedido?** — A quantidade total de cada produto no pedido.
- **2. Quanto já chegou?** — A quantidade que a loja já recebeu.
- **3. Quanto ainda falta?** — A diferença entre o pedido e o recebido.

![Exemplo prático: a loja pediu 10 camisetas, recebeu 7, e o sistema registra que faltam 3.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-qrc9hzbf.png)

Figura 2 — Exemplo prático: a loja pediu 10 camisetas, recebeu 7, e o sistema registra que faltam 3.

## Quando isso acontece?

O processo roda **automaticamente**, sem que ninguém precise clicar em botões. Ele verifica se há pedidos novos ou alterados desde a última vez que rodou e atualiza as informações.

<div class="caixa-simples" id="bkmrk-analogia%3A-%C3%A9-como-um-">**Analogia:** é como um carteiro que passa na loja todo dia, olha a lista de pedidos, anota o que mudou e leva a informação atualizada para o OneBeat.</div>## O que acontece com pedidos cancelados?

Se um pedido for **cancelado** ou ainda estiver **aberto** (não finalizado), o sistema marca esses registros como *desativados* e depois os remove da tabela de envio ao OneBeat.

![Apenas pedidos finalizados permanecem ativos na tabela enviada ao OneBeat.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-6o9sfn1m.png)

Figura 3 — Apenas pedidos finalizados permanecem ativos na tabela enviada ao OneBeat.

## O que o usuário vê na tela?

A tela do módulo (`visual.html`) mostra apenas uma mensagem de confirmação: **"Carregado onebeat\_pedidos\_faturados com sucesso!"**. Não há formulários nem botões para o usuário comum.

<div class="caixa-tecnica" id="bkmrk-para-o-diretor-de-t.">**Para o diretor de T.I.:** a interface é mínima por design. O valor do módulo está na rotina `run()`, executada via agendador (cron) ou chamada direta à URL `/bibliotecas/6b5b2af8-ab25-4135-9551-b3cb3e055f1a/onebeat_pedidos_faturados/run`.</div>

# Instalação e preparação

O arquivo `instalador.php` cuida dessa preparação em **duas etapas**, chamadas `v1` e `v2`. Cada etapa deve ser executada na ordem.

![Fluxo de instalação: primeiro cria o banco (v1), depois cria a tabela (v2).](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-4ryxdjdf.png)

Figura 4 — Fluxo de instalação: primeiro cria o banco (v1), depois cria a tabela (v2).

## Etapa 1 — Criar o banco de dados (v1)

<table id="bkmrk-item-detalhe-m%C3%A9todo-"><tbody><tr><th>Item</th><th>Detalhe</th></tr><tr><td>Método</td><td>`instalador::v1()`</td></tr><tr><td>Ação</td><td>`CREATE DATABASE IF NOT EXISTS franquia_osklen_relatorio`</td></tr><tr><td>Retorno de sucesso</td><td>`setSubmit(true, "Feito")`</td></tr><tr><td>Em caso de erro</td><td>Exceção registrada via `error_byexception()`</td></tr></tbody></table>

<div class="caixa-tecnica" id="bkmrk-url-de-instala%C3%A7%C3%A3o%3A%2Fb">**URL de instalação:**  
`/bibliotecas/6b5b2af8-ab25-4135-9551-b3cb3e055f1a/onebeat_pedidos_faturados/install`  
O instalador herda de `biblioteca` e usa a classe `util` para executar SQL com permissão elevada (`query($sql, true)`).</div>## Etapa 2 — Criar a tabela (v2)

A tabela `franquia_1beat` é criada com todos os campos necessários para armazenar pedidos, recebimentos e informações da filial. Detalhes completos no capítulo 7.

<table id="bkmrk-caracter%C3%ADstica-valor"><tbody><tr><th>Característica</th><th>Valor</th></tr><tr><td>Motor</td><td>InnoDB</td></tr><tr><td>Charset</td><td>utf8mb4</td></tr><tr><td>Chave primária</td><td>ID\_PRODUTO\_GRADE + COD\_FILIAL + ID\_FILIAL + ID\_MOVIMENTACAO\_PAI + CNPJ\_FILIAL</td></tr><tr><td>Índice adicional</td><td>IDX\_1BEAT\_SKU (campo SKU)</td></tr></tbody></table>

![Estrutura criada pelo instalador: um banco com uma tabela principal.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-xxndcfle.png)

Figura 5 — Estrutura criada pelo instalador: um banco com uma tabela principal.

## Dependências

<div class="caixa-tecnica" id="bkmrk-classe-base-bibliote">- Classe base `biblioteca` (framework ISNAPP)
- Classe `util` do token `12262a22-30ab-11e9-bb4c-127101af6b0d`
- Array `$requires` está vazio — sem dependências de outras bibliotecas versionadas
- Bancos do tenant já devem existir: `{banco}`, `{banco}_relatorio`, `{banco}_integrador`

</div><div class="caixa-alerta" id="bkmrk-aten%C3%A7%C3%A3o%3A-a-instala%C3%A7%C3%A3">**Atenção:** a instalação só precisa ser feita *uma vez* por ambiente. Executar novamente é seguro graças ao `IF NOT EXISTS`, mas não é necessário em rotina.</div>

# Arquitetura do sistema

O módulo é uma **biblioteca ISNAPP** (padrão de extensão do ERP) composta por três arquivos e integrada a múltiplos bancos MySQL.

![Arquitetura em camadas: apresentação, lógica PHP e múltiplos bancos MySQL.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-knhkbliz.png)

Figura 6 — Arquitetura em camadas: apresentação, lógica PHP e múltiplos bancos MySQL.

## Bancos de dados envolvidos

<table id="bkmrk-vari%C3%A1vel-php-nome-do"><tbody><tr><th>Variável PHP</th><th>Nome do banco</th><th>Uso</th></tr><tr><td>`$banco`</td><td>Dinâmico (tenant)</td><td>Pedidos, itens, entidades, recebimentos</td></tr><tr><td>`$bancoRelatorio`</td><td>`{banco}_relatorio`</td><td>Tabela `log` com ponteiro de última execução</td></tr><tr><td>`$bancoIntegrador`</td><td>`{banco}_integrador`</td><td>Stage de integração LX (`stage_pedido_lx`)</td></tr><tr><td>`$bancoMasterRelatorio`</td><td>`franquia_osklen_relatorio`</td><td>Tabela de destino `franquia_1beat` (compartilhada)</td></tr></tbody></table>

<div class="caixa-simples" id="bkmrk-para-entender-sem-ja">**Para entender sem jargão:** o sistema lê informações de três "pastas" diferentes no banco de dados e grava o resultado organizado em uma "pasta central" que o OneBeat consulta.</div>## Tabelas de origem (leitura)

<table id="bkmrk-tabela-banco-papel-m"><tbody><tr><th>Tabela</th><th>Banco</th><th>Papel</th></tr><tr><td>`movimentacao`</td><td>{banco}</td><td>Cabeçalho dos pedidos e recebimentos</td></tr><tr><td>`movimentacao_detalhe`</td><td>{banco}</td><td>Itens (produtos) de cada movimentação</td></tr><tr><td>`movimentacao_movimentacao`</td><td>{banco}</td><td>Vínculo pai-filho (pedido → recebimento)</td></tr><tr><td>`entidade`</td><td>{banco}</td><td>Dados da filial (loja)</td></tr><tr><td>`juridica`</td><td>{banco}</td><td>CNPJ da filial</td></tr><tr><td>`stage_pedido_lx`</td><td>{banco}\_integrador</td><td>Integração com sistema LX (LEFT JOIN)</td></tr><tr><td>`log`</td><td>{banco}\_relatorio</td><td>Controle de ponteiro (`procedure = 'franquia_1beat'`)</td></tr></tbody></table>

## Classe principal

**Classe:** `onebeat_pedidos_faturados` extends `util`

**Token:** `6b5b2af8-ab25-4135-9551-b3cb3e055f1a`

**CoreVersion:** 3

**Métodos públicos principais:**

<div class="caixa-tecnica" id="bkmrk-index%28%29-%E2%80%94-exibe-visu">- `index()` — exibe visual.html
- `run()` — execução principal (sincronização)
- `verificaGetLock()` — controle de concorrência
- `getPonteiroExecucao()` — última data processada
- `getPedidoUltimaVerificacao()` — data do pedido mais recente
- `getPedidosRecebidos()` — INSERT/UPDATE na tabela destino
- `removePedidosStatus()` — limpeza de registros desativados
- `atualizaPonteiroExecucao()` — grava novo ponteiro

</div>## Mecanismo de lock (concorrência)

Para evitar que duas execuções rodem ao mesmo tempo, o módulo usa um **arquivo de lock** no diretório temporário do sistema operacional:

`/tmp/{banco}.onebeat_pedidos_faturados_run.lock`

<div class="caixa-tecnica" id="bkmrk-usa-flock%28lock_ex-%7C-">Usa `flock(LOCK_EX | LOCK_NB)` — lock exclusivo não-bloqueante. Se outro processo já estiver rodando, lança exceção: *"Ja tem outro processo em execucao, aguarde o termino"*. O lock é liberado no bloco `finally` via `__releaseLock()`.</div>

# Fluxo de execução principal

<div class="caixa-simples" id="bkmrk-"></div>![Fluxograma completo do método run(), com 6 etapas e liberação do lock no finally.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-yyyaljd3.png)

Figura 7 — Fluxograma completo do método run(), com 6 etapas e liberação do lock no finally.

## Detalhamento de cada etapa

<table id="bkmrk-%23-m%C3%A9todo-o-que-faz-%28"><tbody><tr><th>\#</th><th>Método</th><th>O que faz (simples)</th><th>O que faz (técnico)</th></tr><tr><td>1</td><td>`verificaGetLock()`</td><td>Garante que só uma cópia rode por vez</td><td>`flock` exclusivo em arquivo temporário</td></tr><tr><td>2</td><td>`getPonteiroExecucao()`</td><td>Pergunta: "desde quando devo buscar?"</td><td>`MAX(execucao)` em `log` onde `procedure='franquia_1beat'`</td></tr><tr><td>3</td><td>`getPedidoUltimaVerificacao()`</td><td>Acha o pedido mais novo no período</td><td>`MAX(data)` em movimentação PEDIDO &gt; ponteiro</td></tr><tr><td>4</td><td>`getPedidosRecebidos()`</td><td>Copia e calcula quantidades</td><td>INSERT com CTEs + ON DUPLICATE KEY UPDATE</td></tr><tr><td>5</td><td>`removePedidosStatus()`</td><td>Apaga pedidos cancelados/abertos</td><td>`DELETE WHERE SITUACAO = 'DESATIVO'`</td></tr><tr><td>6</td><td>`atualizaPonteiroExecucao()`</td><td>Marca que terminou até tal data</td><td>INSERT/UPDATE em `log`</td></tr></tbody></table>

## Processamento incremental

O módulo **não reprocessa tudo** a cada execução. Ele usa um "marcador de página" (ponteiro) para buscar apenas pedidos alterados entre a última execução e a data do pedido mais recente.

![Apenas pedidos entre o ponteiro e a data mais recente são processados em cada execução.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-gexpp800.png)

Figura 8 — Apenas pedidos entre o ponteiro e a data mais recente são processados em cada execução.

## Mensagens de erro comuns

<div class="caixa-erro" id="bkmrk-%22ja-tem-outro-proces">- **"Ja tem outro processo em execucao, aguarde o termino"** — outra instância do `run()` está ativa.
- **"Não foram encontrados pedidos para atualizar"** — não há pedidos novos desde o ponteiro.
- **"Nao foi possivel criar o arquivo de lock"** — problema de permissão no diretório temporário.

</div><div class="caixa-tecnica" id="bkmrk-tratamento-de-erros%3A">**Tratamento de erros:** exceções no `run()` são capturadas e enviadas a `error_byexception()`. Os métodos intermediários (`getPedidosRecebidos`, `removePedidosStatus`, `atualizaPonteiroExecucao`) também possuem try/catch interno que retorna `null` em falha sem interromper o fluxo principal.</div>

# Como os dados são processados

O método `getPedidosRecebidos()` executa um único comando SQL complexo que usa **CTEs** (Common Table Expressions — subconsultas nomeadas) para organizar os dados em etapas.

![As CTEs organizam pedidos, itens e recebimentos antes do INSERT final.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-yhvf8pxn.png)

Figura 9 — As CTEs organizam pedidos, itens e recebimentos antes do INSERT final.

## Etapa por etapa

### 1. CTE `m` — Pedidos no período

Seleciona movimentações do tipo PEDIDO alteradas entre o ponteiro e a data limite. Faz LEFT JOIN com `stage_pedido_lx` para integração LX.

### 2. CTE `mi` — Itens do pedido

Para cada pedido, soma as quantidades de cada produto (grade) nos itens ativos do pedido.

### 3. CTE `mr` — Recebimentos vinculados

Busca movimentações filhas (recebimentos) ligadas ao pedido pai, apenas com situação `Finalizado`.

### 4. CTE `mri` — Itens recebidos

Soma as quantidades recebidas de cada produto em cada recebimento vinculado ao pedido.

### 5. SELECT final — Montagem do registro

Junta pedido + itens pedidos + itens recebidos + dados da filial (nome, CNPJ, código).

![Cálculo da quantidade pendente: pedido menos recebido, nunca negativo.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-gbswx0yp.png)

Figura 10 — Cálculo da quantidade pendente: pedido menos recebido, nunca negativo.

## Campos calculados

<table id="bkmrk-campo-destino-como-%C3%A9"><tbody><tr><th>Campo destino</th><th>Como é calculado</th></tr><tr><td>`QTDE_PEDIDA`</td><td>Soma dos itens do pedido (`mi.qtde`)</td></tr><tr><td>`QTDE_RECEBIDA`</td><td>Soma dos itens recebidos (`COALESCE(mri.qtde, 0)`)</td></tr><tr><td>`QTDE_PENDENTE`</td><td>`IF((pedida - recebida) < 0, 0, pedida - recebida)`</td></tr><tr><td>`ENTRADA_CONFIRMADA`</td><td>`1` se situação = FINALIZADO, senão `0`</td></tr><tr><td>`SITUACAO`</td><td>`DESATIVO` se Cancelado/Aberto, senão `ATIVO`</td></tr><tr><td>`DATA_TRANSFERENCIA`</td><td>`NOW()` no momento da gravação</td></tr><tr><td>`SKU`</td><td>Código do produto (`mi.codigo`)</td></tr><tr><td>`CHAVE_NFE`</td><td>Chave da nota fiscal do pedido</td></tr></tbody></table>

## Atualização de registros existentes

O INSERT usa `ON DUPLICATE KEY UPDATE`, ou seja:

<div class="caixa-tecnica" id="bkmrk-se-o-registro-n%C3%A3o-ex">- Se o registro **não existe** (chave primária nova) → insere.
- Se o registro **já existe** → atualiza apenas: QTDE\_RECEBIDA, QTDE\_PENDENTE, QTDE\_PEDIDA, ENTRADA\_CONFIRMADA, DATA\_TRANSFERENCIA e SITUACAO.

</div>Chave primária: `ID_PRODUTO_GRADE + COD_FILIAL + ID_FILIAL + ID_MOVIMENTACAO_PAI + CNPJ_FILIAL`

## Filtros aplicados

<table id="bkmrk-filtro-valor-motivo-"><tbody><tr><th>Filtro</th><th>Valor</th><th>Motivo</th></tr><tr><td>`modulo`</td><td>'PEDIDO'</td><td>Apenas movimentações de pedido</td></tr><tr><td>`tipo_estoque`</td><td>'PEDIDO'</td><td>Confirma tipo de estoque</td></tr><tr><td>`m.data`</td><td>&gt; ponteiro AND &lt;= limite</td><td>Janela incremental</td></tr><tr><td>`md.situacao`</td><td>'ATIVO'</td><td>Itens não excluídos</td></tr><tr><td>`md.id_produto_grade`</td><td>IS NOT NULL</td><td>Produtos com grade definida</td></tr><tr><td>`mr.situacao`</td><td>'Finalizado'</td><td>Recebimentos concluídos</td></tr></tbody></table>

<div class="rodape-nav" id="bkmrk-%E2%86%90-anterior%3A-fluxo-de"></div>

# Estrutura da tabela de destino

<div class="caixa-simples" id="bkmrk-"></div>![Campos da tabela organizados por grupo: produto, filial, quantidades, pedido e controle.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-ajiehjmp.png)

Figura 11 — Campos da tabela organizados por grupo: produto, filial, quantidades, pedido e controle.

## Todos os campos

<table id="bkmrk-campo-tipo-significa"><tbody><tr><th>Campo</th><th>Tipo</th><th>Significado (simples)</th><th>Detalhe técnico</th></tr><tr><td>`SKU`</td><td>varchar(45)</td><td>Código do produto</td><td>Vem de `movimentacao_detalhe.codigo`</td></tr><tr><td>`CHAVE_NFE`</td><td>varchar(45)</td><td>Número da nota fiscal</td><td>Chave da NF-e do pedido</td></tr><tr><td>`ID_FILIAL`</td><td>int</td><td>Identificador da loja</td><td>FK para `entidade.id`</td></tr><tr><td>`NOME_FILIAL`</td><td>varchar(45)</td><td>Nome da loja</td><td>`entidade.nome`</td></tr><tr><td>`CNPJ_FILIAL`</td><td>varchar(50)</td><td>CNPJ da loja</td><td>`juridica.cnpj` — parte da PK</td></tr><tr><td>`COD_FILIAL`</td><td>varchar(45)</td><td>Código interno da loja</td><td>`entidade.codigo` — parte da PK</td></tr><tr><td>`QTDE_PEDIDA`</td><td>decimal(10,2)</td><td>Quanto foi pedido</td><td>Soma dos itens do pedido</td></tr><tr><td>`QTDE_RECEBIDA`</td><td>decimal(10,2)</td><td>Quanto já chegou</td><td>Soma dos recebimentos finalizados</td></tr><tr><td>`QTDE_PENDENTE`</td><td>decimal(10,2)</td><td>Quanto falta</td><td>pedida − recebida (mínimo 0)</td></tr><tr><td>`DESCRICAO`</td><td>longtext</td><td>Nome/descrição do produto</td><td>Texto do item do pedido</td></tr><tr><td>`ID_MOVIMENTACAO_PAI`</td><td>int</td><td>Número do pedido no sistema</td><td>ID da movimentação pai — parte da PK</td></tr><tr><td>`ID_PRODUTO_GRADE`</td><td>int</td><td>Identificador do produto com tamanho/cor</td><td>Parte da PK</td></tr><tr><td>`ENTRADA_CONFIRMADA`</td><td>int</td><td>Pedido já foi finalizado? (1=sim, 0=não)</td><td>Baseado em `m.situacao = 'FINALIZADO'`</td></tr><tr><td>`DATA_EMISSAO`</td><td>timestamp</td><td>Data em que o pedido foi emitido</td><td>`movimentacao.data_emissao`</td></tr><tr><td>`DATA_TRANSFERENCIA`</td><td>timestamp</td><td>Quando os dados foram enviados ao OneBeat</td><td>`NOW()` na gravação</td></tr><tr><td>`SITUACAO`</td><td>enum</td><td>Se o registro está valendo (ATIVO) ou não (DESATIVO)</td><td>ATIVO ou DESATIVO</td></tr><tr><td>`EXTRA`</td><td>json</td><td>Campo reservado para dados extras</td><td>Não preenchido pelo módulo atualmente</td></tr><tr><td>`DATA_CRIACAO`</td><td>timestamp</td><td>Quando o registro foi criado</td><td>DEFAULT CURRENT\_TIMESTAMP</td></tr><tr><td>`DATA_ATUALIZACAO`</td><td>timestamp</td><td>Última alteração do registro</td><td>ON UPDATE CURRENT\_TIMESTAMP</td></tr></tbody></table>

## Chave primária e índices

![Chave primária composta por 5 campos garante um registro único por produto/pedido/filial.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-n2wenyar.png)

Figura 12 — Chave primária composta por 5 campos garante um registro único por produto/pedido/filial.

Índice adicional: `IDX_1BEAT_SKU` no campo `SKU` para consultas rápidas por código de produto.

# Regras de negócio e situações

O módulo lê a situação do pedido na tabela `movimentacao` e traduz para o campo `SITUACAO` da tabela destino.

<table id="bkmrk-" style="width:100%;max-width:720px;margin:1.5rem auto;border:0;border-collapse:separate;border-spacing:0 0.75rem;table-layout:fixed;font-family:inherit;font-size:0.95rem;"><colgroup> <col style="width:44%;"></col> <col style="width:6%;"></col> <col style="width:50%;"></col> </colgroup><tbody><tr><td style="text-align:center;font-weight:600;color:#2c3e50;border:0;padding:0;">Situação no ERP</td><td style="border:0;padding:0;"> </td><td style="text-align:center;font-weight:600;color:#2c3e50;border:0;padding:0;">Na tabela OneBeat</td></tr><tr><td style="text-align:center;vertical-align:middle;border:0;padding:0 0.5rem 0 0;"><div style="background:#d5f5e3;border:2px solid #27ae60;padding:0.75rem 1rem;color:#1e8449;line-height:1.6;">Confirmado  
Recebido  
Atendido Parcialmente  
Finalizado</div></td><td style="text-align:center;vertical-align:middle;color:#3498db;font-size:1.5rem;border:0;padding:0;">→</td><td style="text-align:center;vertical-align:middle;border:0;padding:0 0 0 0.5rem;"><div style="background:#d5f5e3;border:2px solid #27ae60;padding:0.75rem 1rem;color:#1e8449;font-weight:600;">ATIVO</div></td></tr><tr><td style="text-align:center;vertical-align:middle;border:0;padding:0 0.5rem 0 0;"><div style="background:#fdebd0;border:2px solid #f39c12;padding:0.75rem 1rem;color:#b9770e;font-weight:600;">Aberto</div></td><td style="text-align:center;vertical-align:middle;color:#3498db;font-size:1.5rem;border:0;padding:0;">→</td><td style="vertical-align:middle;border:0;padding:0 0 0 0.5rem;"><table style="width:100%;border:0;border-collapse:collapse;table-layout:fixed;"><tbody><tr><td style="text-align:center;vertical-align:middle;border:0;padding:0 0.25rem 0 0;"><div style="background:#fadbd8;border:2px solid #e74c3c;padding:0.75rem 0.5rem;color:#c0392b;font-weight:600;">DESATIVO (removido)</div></td><td style="width:1.75rem;text-align:center;vertical-align:middle;color:#3498db;font-size:1.5rem;border:0;padding:0;">→</td><td style="width:5.5rem;text-align:center;vertical-align:middle;border:0;padding:0 0 0 0.25rem;"><div style="background:#f5b7b1;border:2px solid #e74c3c;padding:0.75rem 0.5rem;color:#922b21;font-weight:bold;">DELETE</div></td></tr></tbody></table>

</td></tr><tr><td style="text-align:center;vertical-align:middle;border:0;padding:0 0.5rem 0 0;"><div style="background:#fadbd8;border:2px solid #e74c3c;padding:0.75rem 1rem;color:#c0392b;font-weight:600;">Cancelado</div></td><td style="text-align:center;vertical-align:middle;color:#3498db;font-size:1.5rem;border:0;padding:0;">→</td><td style="text-align:center;vertical-align:middle;border:0;padding:0 0 0 0.5rem;"><div style="background:#fadbd8;border:2px solid #e74c3c;padding:0.75rem 1rem;color:#c0392b;font-weight:600;">DESATIVO</div></td></tr></tbody></table>

Figura 13 — Pedidos abertos e cancelados viram DESATIVO e são removidos da tabela após a sincronização.

## Regra da quantidade pendente

<div class="caixa-simples" id="bkmrk-regra-simples%3A-o-que">**Regra simples:** o que falta = o que foi pedido menos o que já chegou. Se por algum motivo o recebido for maior que o pedido, o sistema considera que **nada falta** (zero).</div><table id="bkmrk-pedido-recebido-pend"><tbody><tr><th>Pedido</th><th>Recebido</th><th>Pendente</th><th>Explicação</th></tr><tr><td>10</td><td>7</td><td>3</td><td>Caso normal: faltam 3 unidades</td></tr><tr><td>10</td><td>10</td><td>0</td><td>Pedido completo</td></tr><tr><td>10</td><td>0</td><td>10</td><td>Nada recebido ainda</td></tr><tr><td>5</td><td>8</td><td>0</td><td>Recebido a mais: pendente nunca fica negativo</td></tr></tbody></table>

## Entrada confirmada

O campo `ENTRADA_CONFIRMADA` indica se o pedido foi finalizado no ERP:

<table id="bkmrk-valor-significado-co"><tbody><tr><th>Valor</th><th>Significado</th><th>Condição</th></tr><tr><td>1</td><td>Entrada confirmada</td><td>`m.situacao = 'FINALIZADO'`</td></tr><tr><td>0</td><td>Entrada não confirmada</td><td>Qualquer outra situação</td></tr></tbody></table>

## Recebimentos considerados

Para contar como "recebido", uma movimentação filha deve atender **todos** estes critérios:

<div class="caixa-tecnica" id="bkmrk-estar-vinculada-ao-p">- Estar vinculada ao pedido pai via `movimentacao_movimentacao`
- Ter situação `'Finalizado'` (com F maiúsculo)
- Ter itens ativos com `id_produto_grade` preenchido

</div>Recebimentos em andamento ou cancelados **não entram** no cálculo de QTDE\_RECEBIDA.

## Processamento incremental

![O módulo foi projetado para rodar repetidamente, processando apenas o que mudou desde a última vez.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-bci1zivx.png)

Figura 14 — O módulo foi projetado para rodar repetidamente, processando apenas o que mudou desde a última vez.

## Concorrência — apenas uma execução por vez

<div class="caixa-alerta" id="bkmrk-regra-de-seguran%C3%A7a%3A-">**Regra de segurança:** se duas execuções tentarem rodar ao mesmo tempo, a segunda será bloqueada com a mensagem *"Ja tem outro processo em execucao, aguarde o termino"*. Isso evita dados duplicados ou corrompidos.</div>## O que acontece quando não há pedidos novos?

Se não existir nenhum pedido com data maior que o ponteiro, o método `getPedidoUltimaVerificacao()` lança uma exceção: *"Não foram encontrados pedidos para atualizar"*. A execução é interrompida, o lock é liberado, e nada é alterado na tabela destino.

## Ponteiro inicial

<div class="caixa-tecnica" id="bkmrk-na-primeira-execu%C3%A7%C3%A3o">Na primeira execução (sem registro em `log`), o ponteiro padrão é `2000-01-01 00:00:00`, ou seja, todos os pedidos desde essa data serão considerados.</div>

# Glossário e referência rápida

<dl id="bkmrk-onebeat-sistema-exte"><dt></dt><dd>One Beat  
Sistema externo de gestão de estoque e abastecimento que consome os dados desta tabela.</dd><dt>ERP / ISNAPP</dt><dd>Sistema principal da empresa onde os pedidos são criados e os recebimentos registrados.</dd><dt>Pedido faturado</dt><dd>Pedido de produtos emitido pela matriz para uma loja, com nota fiscal associada.</dd><dt>Recebimento</dt><dd>Registro de que a loja recebeu (ou parte de) um pedido. Fica ligado ao pedido original.</dd><dt>Filial / Loja</dt><dd>Unidade da franquia que faz o pedido e recebe os produtos.</dd><dt>SKU</dt><dd>Código único do produto (como um "RG" do item no estoque).</dd><dt>Grade</dt><dd>Variação do produto (tamanho, cor). Exemplo: camiseta azul tamanho M.</dd><dt>Ponteiro de execução</dt><dd>Data/hora da última sincronização bem-sucedida. O sistema só busca pedidos alterados depois dessa data.</dd><dt>Lock (trava)</dt><dd>Mecanismo que impede duas cópias do programa de rodar ao mesmo tempo.</dd><dt>CTE (Common Table Expression)</dt><dd>Técnica SQL que organiza a consulta em etapas nomeadas (m, mi, mr, mri).</dd><dt>ON DUPLICATE KEY UPDATE</dt><dd>Comando SQL que insere um registro novo ou atualiza se ele já existir (pela chave primária).</dd><dt>Biblioteca ISNAPP</dt><dd>Módulo extensível do ERP, identificado por um token UUID único.</dd><dt>Tenant / Banco dinâmico</dt><dd>Cada cliente/franquia tem seu próprio banco de dados ({banco}), separado dos demais.</dd><dt>Stage (integrador)</dt><dd>Área intermediária de integração com sistemas externos, como o LX.</dd><dt>NF-e / CHAVE\_NFE</dt><dd>Nota Fiscal Eletrônica. A chave é o número de 44 dígitos que identifica a nota.</dd></dl>## URLs do módulo

<table id="bkmrk-fun%C3%A7%C3%A3o-url-tela-visu"><tbody><tr><th>Função</th><th>URL</th></tr><tr><td>Tela visual</td><td>`/bibliotecas/6b5b2af8-ab25-4135-9551-b3cb3e055f1a/onebeat_pedidos_faturados`</td></tr><tr><td>Execução (run)</td><td>`/bibliotecas/6b5b2af8-ab25-4135-9551-b3cb3e055f1a/onebeat_pedidos_faturados/run`</td></tr><tr><td>Instalação</td><td>`/bibliotecas/6b5b2af8-ab25-4135-9551-b3cb3e055f1a/onebeat_pedidos_faturados/install`</td></tr></tbody></table>

## Checklist de implantação (T.I.)

![Checklist recomendado para implantação do módulo.](https://kb.illimitar.pro/uploads/images/gallery/2026-06/embedded-image-vz1ggczi.png)

Figura 15 — Checklist recomendado para implantação do módulo.

## Resumo dos arquivos

<table id="bkmrk-arquivo-classe-respo"><tbody><tr><th>Arquivo</th><th>Classe</th><th>Responsabilidade</th></tr><tr><td>`controle.php`</td><td>`onebeat_pedidos_faturados`</td><td>Sincronização de pedidos</td></tr><tr><td>`instalador.php`</td><td>`instalador`</td><td>Criação de banco e tabela</td></tr><tr><td>`visual.html`</td><td>—</td><td>Mensagem de carregamento</td></tr></tbody></table>

## Identificadores do módulo

<table id="bkmrk-propriedade-valor-to"><tbody><tr><th>Propriedade</th><th>Valor</th></tr><tr><td>Token</td><td>`6b5b2af8-ab25-4135-9551-b3cb3e055f1a`</td></tr><tr><td>Classe</td><td>`onebeat_pedidos_faturados`</td></tr><tr><td>CoreVersion</td><td>3</td></tr><tr><td>Banco destino</td><td>`franquia_osklen_relatorio`</td></tr><tr><td>Tabela destino</td><td>`franquia_1beat`</td></tr><tr><td>Procedure no log</td><td>`franquia_1beat`</td></tr></tbody></table>

<div class="caixa-simples" id="bkmrk-d%C3%BAvidas-frequentes%3A-">**Dúvidas frequentes:**- *"O sistema não atualizou meu pedido"* — verifique se o agendamento do `run()` está ativo e se o pedido tem data maior que o ponteiro.
- *"Apareceu erro de processo em execução"* — aguarde a execução anterior terminar ou verifique se há lock órfão em `/tmp/`.
- *"Pedido cancelado ainda aparece"* — na próxima execução ele será marcado DESATIVO e removido.

</div>## Índice da documentação

<table id="bkmrk-%23-cap%C3%ADtulo-arquivo-0"><tbody><tr><th>\#</th><th>Capítulo</th><th>Arquivo</th></tr><tr><td>01</td><td>Introdução</td><td>`01_introducao.html`</td></tr><tr><td>02</td><td>O que faz</td><td>`02_o_que_faz.html`</td></tr><tr><td>03</td><td>Instalação</td><td>`03_instalacao.html`</td></tr><tr><td>04</td><td>Arquitetura</td><td>`04_arquitetura.html`</td></tr><tr><td>05</td><td>Fluxo de execução</td><td>`05_fluxo_execucao.html`</td></tr><tr><td>06</td><td>Processamento de dados</td><td>`06_processamento_dados.html`</td></tr><tr><td>07</td><td>Estrutura da tabela</td><td>`07_estrutura_tabela.html`</td></tr><tr><td>08</td><td>Regras de negócio</td><td>`08_regras_negocio.html`</td></tr><tr><td>09</td><td>Glossário</td><td>`09_glossario.html`</td></tr></tbody></table>

<div class="rodape-nav" id="bkmrk-%E2%86%90-anterior%3A-regras-d"></div>