Objetivo
Verificar automaticamente a coerência entre os três documentos (OCR, Pedido de venda, REQ de produção) no exato momento em que o pedido entra em Ag. Impressão. Se aceito, gerar um JSON consolidado que será consumido pela API de impressão de rótulos (createLabel). Se rejeitado, devolver o pedido para Pago com o motivo da rejeição, para que o responsável corrija antes de tentar novamente.
Este processo existe porque Ag. Impressão é o ponto de cristalização dos dados: os rótulos são gerados a partir do JSON consolidado, e qualquer erro nos dados após esse ponto exige retrabalho caro (reimprimir, remarcar, reconferir). A conferência automática é a barreira que impede dados inconsistentes de cristalizarem.
Posição no fluxo do ERP
- Etapa: Aguardando impressão — etapa 5
- Padrão de avanço: Automático por evento externo (webhook)
- Disparador: O webhook “pedido entrou em Ag. Impressão” é emitido quando o Atendente (ou futuro Setor de Pedidos) avança o pedido de Pago para Ag. Impressão via Geração de REQ
- Se aceito: Pedido permanece em Ag. Impressão. JSON consolidado fica disponível para impressão de rótulos.
- Se rejeitado: Pedido volta para Pago. O responsável pela execução recebe o motivo detalhado.
Como funciona
Fase 1 — Captura dos dados das 3 fontes
O webhook dispara a coleta automática dos dados de cada fonte. O agente verificador acessa:
- OCR — dados da prescrição digitalizada: prescritor, paciente, composição por fórmula, posologia, base/veículo, volume, quantidade de frascos
- Pedido de venda (ERP de vendas) — cliente, produtos comprados, quantidades, preços, endereço de entrega, tipo de envio, observações
- REQ de produção (ERP de produção) — composição técnica por produto (items[], composition), volume por unidade, conteúdo total, forma farmacêutica, paciente e prescritor por produto, charge
O casamento entre fontes segue as regras de Conferência de Pedidos:
- Pedido ↔ REQ: determinístico (reqNumber + reqSerie)
- OCR ↔ (Pedido + REQ): heurístico (nome, volume, composição, código de ingrediente)
Fase 2 — Conferência em dois níveis
A conferência segue a mesma estrutura de conferencia-pedido-ocr, aplicada automaticamente:
Nível 1 — Bloco global do pedido:
- Entidades de pessoa (prescritor, paciente, comprador, destinatário) consistentes entre OCR, Pedido e Chat
- Endereço de entrega coerente
- Tipo de envio coerente
- Contagem de itens: total no Pedido = total de séries na REQ = total de fórmulas no OCR
- Preço total: somatório dos charges das REQs = preço total do Pedido
- Consistência de datas e horas (ver abaixo)
Nível 2 — Bloco por produto (para cada série da REQ):
- Identificação: nome e quantidade consistentes entre OCR, Pedido e REQ
- Apresentação: forma farmacêutica + base/veículo + volume + conteúdo + embalagem coerentes (ver tabela de compatibilidade ff↔base↔uso)
- Composição: comparação ativo a ativo entre OCR e REQ (usando tabela de sinônimos)
- Posologia: OCR vs REQ (truncamento na REQ é aceito; contradição real não)
- Pessoas: paciente e prescritor da REQ (por produto) vs valores globais do OCR e Pedido
Verificação de datas e horas (Nível 1)
Além dos dados de produto, o agente verificador confere a consistência temporal entre PV e REQ. Estas regras garantem que a produção receberá informações de data e hora coerentes, evitando problemas nos filtros e na priorização da fila. Ver regras-datas-filtros-producao para contexto completo.
Regras de hora (bloqueiam se violadas):
| Verificação | Fonte A | Fonte B | Regra | Efeito |
|---|---|---|---|---|
| Hora entre dígitos da REQ | REQ dígito 1 | REQ dígito N | Todas as horas iguais | ❌ Rejeita se diferente |
| Hora × tipo de envio | REQ hora | PV tipo de envio | Hora consistente com tipo | ❌ Rejeita se inconsistente (hora :00) |
| Hora × tipo de envio (esporádico) | REQ hora | PV tipo de envio | — | ✅ Não valida se hora :30 (esporádico/extra por definição) |
Regras de data (alertam mas não bloqueiam):
| Verificação | Fonte A | Fonte B | Regra | Efeito |
|---|---|---|---|---|
| Data de retirada × previsão | REQ data retirada | PV previsão de produção | Retirada ≥ Previsão | ⚠️ Alerta se retirada < previsão (requer prioridade da gerente) |
| Data de retirada × previsão | REQ data retirada | PV previsão de produção | Retirada > Previsão | ℹ️ Info — pedido será produzido depois do calculado (divergência de filtros ERP × produção) |
| Data entre dígitos da REQ | REQ dígito 1 | REQ dígito N | Todas as datas iguais | ❌ Rejeita se diferente |
A diferença entre bloqueio e alerta é intencional: inconsistências de hora são erros objetivos (hora errada = tipo de envio errado = produção prioriza errado). Inconsistências de data envolvem julgamento humano — o Farm. Triagista na etapa Ag. Triagem é quem questiona a data se o alerta persistir.
Fase 3 — Veredito
O agente classifica cada campo com os indicadores padrão:
| Indicador | Significado | Efeito no veredito |
|---|---|---|
| ✅ | Confere entre as fontes | Nenhum — campo aceito |
| ℹ️ | Informação em uma fonte só, sem correspondente nas outras | Aceito (esperado para excipientes, conservantes) |
| ⚠️ | Divergência que pode ser legítima ou erro | Aceito com flag — campo entra no JSON com divergencia: true |
| ❌ | Inconsistência clara | Rejeita o pedido inteiro |
Critérios de rejeição automática (❌):
- Contagem de itens divergente entre as 3 fontes (produto faltando ou sobrando)
- Ativo presente no OCR ausente na REQ (sem equivalência por sinônimo)
- Forma farmacêutica incompatível com base na REQ
- Nome do paciente divergente entre OCR e REQ sem correspondência parcial
- Preço total divergente acima de margem de tolerância
- Hora diferente entre dígitos da REQ (todos devem ter a mesma hora)
- Data diferente entre dígitos da REQ (todos devem ter a mesma data)
- Hora :00 inconsistente com tipo de envio do PV (ex: hora 15:00 mas tipo de envio é 12h)
Critérios de aceitação com flag (⚠️):
- Nomes levemente diferentes mas identificáveis como a mesma pessoa
- Concentração arredondada (OCR: “0,5%”; REQ: “0,50%”)
- Posologia truncada na REQ mas sem contradição
- Volume em ml vs g (aceito com flag, densidade ~1)
- Data de retirada < previsão de produção (sem prioridade marcada — alerta para o Farm. Triagista verificar na etapa Ag. Triagem)
Critérios de aceitação com informação (ℹ️):
- Data de retirada > previsão de produção — legítimo, mas sinaliza divergência entre filtros do ERP e do sistema de produção
- Hora :30 (esporádico ou extra) — não valida hora × tipo de envio por definição
Fase 4a — Se aceito: gerar JSON consolidado e PDF do rótulo
O agente gera o JSON consolidado e, a partir dele, o PDF do rótulo de cada produto. Este é o momento em que os dados cristalizam: o sistema pega os 3 “paciente” (OCR, PV, REQ), escolhe o paciente do OCR como fonte prioritária, e preenche o JSON final. A API createLabel lê o JSON e gera os PDFs dos rótulos. A partir daqui, o rótulo reflete os dados consolidados — qualquer erro nos dados exige voltar até Pago para corrigir e regenerar.
Estrutura do JSON consolidado:
{
"pedido_id": "string — ID do pedido de venda",
"req_number": "string — número da REQ (6 dígitos)",
"data_conferencia": "ISO 8601 — timestamp da conferência",
"veredito": "aceito | aceito_com_flags",
"flags_count": 0,
"bloco_global": {
"paciente": {
"nome": "string — nome escolhido (fonte prioritária: OCR)",
"fonte": "ocr | pedido | req",
"divergencia": false
},
"prescritor": {
"nome": "string",
"conselho": "string — CRM/CRO/etc",
"numero_conselho": "string",
"fonte": "ocr",
"divergencia": false
},
"comprador": {
"nome": "string",
"documento": "string — CPF/CNPJ",
"fonte": "pedido"
},
"destinatario": {
"nome": "string",
"endereco": {
"logradouro": "string",
"numero": "string",
"complemento": "string",
"bairro": "string",
"cidade": "string",
"uf": "string",
"cep": "string"
},
"fonte": "pedido",
"divergencia_chat": false
},
"envio": {
"tipo": "string — tipo de envio do PV",
"hora_req": "string — hora de retirada da REQ (ex: 15:00 ou 17:30)",
"esporadico": false,
"conferencia_hora_tipo": "ok | esporadico_sem_validacao | divergente",
"fonte": "pedido + req"
},
"datas": {
"previsao_producao_pv": "ISO 8601 — data de previsão calculada no PV",
"retirada_req": "ISO 8601 — data de retirada inserida no REQ",
"divergencia_tipo": "null | postergado | antecipado",
"prioridade_marcada": false,
"alerta": "null | retirada_anterior_sem_prioridade | retirada_posterior_divergencia_filtros",
"conferencia_datas_digitos": "ok | divergente"
},
"observacoes": "string — observações consolidadas do pedido e chat",
"preco_total": {
"valor": 0.00,
"conferencia": "ok | divergente",
"pedido_valor": 0.00,
"req_soma_charges": 0.00
},
"contagem_itens": {
"pedido": 0,
"req_series": 0,
"ocr_formulas": 0,
"conferencia": "ok | divergente"
}
},
"produtos": [
{
"serie": "string — ex: 204583-1",
"req_serie_index": 1,
"identificacao": {
"nome_ocr": "string",
"nome_pedido": "string",
"nome_req": "string",
"nome_consolidado": "string — nome escolhido para o rótulo",
"quantidade": 1,
"divergencia": false
},
"apresentacao": {
"forma_farmaceutica": {
"codigo_ff": "int — código do ERP (1=cápsula, 2=creme, 3=loção...)",
"descricao_ff": "string",
"fonte": "req"
},
"base_veiculo": {
"nome": "string — nome técnico da base (ex: Base Second Skin)",
"nome_ocr": "string — como aparece no OCR (ex: creme)",
"compativel": true
},
"volume_unidade": "string — ex: 30g",
"volume_total": "string — ex: 60g (se 2 unidades)",
"embalagem": "string — tipo de embalagem",
"uso_aplicacao": "string — TOPIC | ORAL",
"uso_destinacao": "string — consultório | home care",
"divergencia": false
},
"composicao": {
"ativos": [
{
"nome_ocr": "string",
"nome_req": "string",
"codigo_ingrediente": "string — código do ERP",
"concentracao_ocr": "string — ex: 1%",
"concentracao_req": "string — ex: 1.00%",
"conferencia": "ok | sinonimo | divergente | ausente_req | excipiente",
"divergencia": false
}
],
"base_qsp": {
"nome": "string",
"volume": "string"
}
},
"posologia": {
"texto_ocr": "string — posologia completa do OCR",
"texto_req": "string — posologia da REQ (pode estar truncada)",
"conferencia": "ok | truncado_sem_contradicao | divergente",
"divergencia": false
},
"pessoas": {
"paciente_req": "string — nome do paciente na REQ (por produto)",
"paciente_global": "string — nome do paciente global (OCR/Pedido)",
"prescritor_req": "string — prescritor na REQ (por produto)",
"prescritor_global": "string — prescritor global (OCR)",
"divergencia": false
},
"preco": {
"charge_req": 0.00,
"preco_pedido": 0.00,
"conferencia": "ok | divergente",
"divergencia": false
}
}
],
"resumo": {
"total_produtos": 0,
"produtos_ok": 0,
"produtos_com_flag": 0,
"campos_com_flag": ["lista dos campos com divergencia=true"],
"detalhes_flags": [
{
"produto_serie": "string",
"campo": "string",
"descricao": "string — o que diverge e entre quais fontes"
}
]
}
}Prioridade de fontes por campo:
| Campo | Fonte prioritária | Fallback | Justificativa |
|---|---|---|---|
| Nome do paciente | OCR | REQ (por produto) | OCR é o documento fundacional |
| Prescritor | OCR | REQ (por produto) | OCR tem dados completos (nome + conselho) |
| Composição | REQ | — | REQ tem composição técnica detalhada (items[]) |
| Concentração | REQ | OCR | REQ tem valores exatos; OCR pode ter arredondamento |
| Volume | REQ | OCR | REQ tem volume.volume e volume.contain separados |
| Forma farmacêutica | REQ | — | Código padronizado do ERP |
| Base/veículo | REQ | OCR | REQ tem nome técnico; OCR tem nome genérico |
| Posologia | OCR | REQ | OCR é mais completo; REQ pode truncar |
| Preço | Pedido | REQ (charge) | Pedido é o registro comercial oficial |
| Endereço | Pedido | Chat (se divergir, flag) | Pedido é o registro oficial |
| Observações | Pedido + Chat | — | Ambas as fontes são complementares |
Fase 4b — Se rejeitado: devolver para Pago
O agente rejeita o pedido e gera um relatório de rejeição:
- O que muda (ERP): Status volta de Ag. Impressão para Pago
- Quem recebe: O responsável pela execução da etapa anterior (Atendente hoje, futuro Setor de Pedidos)
- O que recebe: Lista de inconsistências encontradas, com:
- Qual campo está inconsistente
- O que cada fonte diz
- Qual é a inconsistência (tipo de divergência)
- Sugestão de correção quando possível
O responsável corrige os dados nas fontes relevantes (OCR, Pedido, REQ) e avança novamente para Ag. Impressão, o que dispara nova conferência automática.
Documentos disponíveis no PV após Ag. Impressão
Quando o pedido entra em Ag. Impressão e o JSON é aceito, todos os documentos abaixo ficam disponíveis no PV para download, visualização e impressão. Eles são o pacote completo que o Setor de Impressão imprime e entrega para a produção.
| # | Documento | Fonte | Geração | Quantidade |
|---|---|---|---|---|
| 1 | Arquivo da prescrição | OCR (receita digitalizada) | Já existia no PV (anexada pelo Atendente) | 1 por pedido |
| 2 | Validação da assinatura da prescrição | Sistema de validação | Gerada a partir da assinatura digital do prescritor | 1 por pedido |
| 3 | Comando de produção (ficha de pesagem) | REQ | Gerado a partir dos dados da REQ | 1 por pedido (cobre todos os dígitos) |
| 4 | Rótulos | JSON consolidado (API createLabel) | Gerados automaticamente — cada dígito da REQ gera rótulo(s) na quantidade de itens do produto no PV | N rótulos (1 por unidade de cada produto) |
| 5 | Registro de entrega (se aplicável) | Sistema (botão do avião) | Gerado automaticamente para produtos com flag “registro de entrega” no PV | 1 por produto com flag (só envio 19h) |
Sobre a quantidade de rótulos: Se o PV tem o produto X com quantidade 2, o dígito correspondente na REQ gera 2 rótulos. Cada rótulo identifica uma unidade individual do produto.
O que o Setor de Impressão imprime
O Setor de Impressão imprime todos os 5 documentos listados acima — inclusive o registro de entrega quando existe. É executor puro: imprime tudo que está disponível no PV e avança para Impresso → Ag. Triagem. Não verifica dados.
O pacote impresso é o que a produção recebe para trabalhar:
- A ficha de pesagem (comando de produção) vai para o Manipulador
- Os rótulos vão para a montagem e conferências
- A prescrição e validação de assinatura ficam disponíveis para conferência documental
- O registro de entrega (quando existe) acompanha o pedido até a expedição
Como os documentos são consumidos nas etapas seguintes
-
Triagem técnica — Farm. Triagista recebe o pacote impresso e verifica viabilidade técnica. Se detectar problema, decide para onde voltar (ver Dois tipos de volta do rótulo):
- Erro de dados (inconformidade OCR/PV/REQ) → volta até Pago. Atendente corrige fontes, avança de novo, JSON é regenerado, documentos são reimpressos.
- Falta aviso no rótulo (dados corretos, mas rótulo precisa de aviso adicional) → volta até Ag. Impressão. Setor de Impressão adiciona avisos no PDF, reimprime, avança com PDFs alterados.
-
Conferência 1 (produto × REQ) — O Conferente usa o rótulo (gerado pelo JSON) e compara com a REQ. Como ambos vieram do mesmo JSON verificado, divergências nesse ponto indicam erro de impressão ou manipulação, não erro de dados.
-
Conferência 2 (produto × REQ × Pedido × OCR) — O Conferente faz conferência mais ampla. O JSON serve como referência consolidada. Se o registro de entrega não estiver no pacote impresso (ex: falha na impressão, flag não existia na primeira passagem), a Conferência 2 é o fallback — imprime o registro de entrega neste ponto. Ver Verificação e fallback do registro de entrega especial (envio 19h).
-
Expedição — O registro de entrega (quando existe) acompanha o pacote até a transportadora.
Resumo RACI
| Fase | R (Executa) | A (Presta contas) | C (Consulta) | I (Informado) |
|---|---|---|---|---|
| 1. Captura de dados | Agente verificador (auto) | — | — | — |
| 2. Conferência 2 níveis | Agente verificador (auto) | — | — | — |
| 3. Veredito | Agente verificador (auto) | — | — | — |
| 4a. Gerar JSON (se aceito) | Agente verificador (auto) | — | — | Setor de Impressão |
| 4b. Rejeitar (se rejeitado) | Agente verificador (auto) | — | — | Atendente / Setor Pedidos |
Regras de decisão e escalação
- Rejeição repetida (3+ vezes no mesmo pedido): Escalar para supervisão humana (Setor de Pedidos). Pode indicar problema sistêmico no cadastro ou na criação da REQ.
- Divergência ambígua que o agente não consegue classificar: Aceitar com flag ⚠️ e incluir no resumo. A decisão final fica com o humano no Setor de Impressão ou Conferência.
- OCR ausente ou ilegível: Conferência parcial (Pedido × REQ apenas). Aceitar com flag indicando ausência do OCR. O Setor de Impressão deve estar ciente.
- Produto com composição complexa (10+ ativos): Mesmas regras, mas o agente deve ser mais conservador — preferir ⚠️ a ✅ quando houver dúvida.
Exceções conhecidas
- Pedido consultivo: No consultivo, a prescrição foi gerada pela própria Neofarma, então a coerência OCR × Pedido × REQ deveria ser perfeita. Qualquer divergência em pedido consultivo é candidata a
ocorrencia/falha-sistemica. - Pedido sem OCR (venda sem prescrição): Conferência limitada a Pedido × REQ. Aceitar com flag.
- Produto manipulado com ajuste autorizado: Se houver registro de ajuste (ex: concentração alterada por Farm. Triagista na triagem de um pedido anterior do mesmo paciente), a divergência OCR × REQ pode ser legítima. O agente deve verificar se existe registro de ajuste antes de rejeitar.
Relação com outros processos
- Recebe de: Geração de REQ — o pedido chega em Ag. Impressão após geração da REQ
- Regras de conferência definidas em: Conferência de Pedidos (OCR × Pedido × REQ × Chat) — este processo automatiza aquelas regras
- Regras de datas e horas: regras-datas-filtros-producao — define as 3 datas, tipos de envio, e regras de consistência temporal validadas aqui
- Entrega para (se aceito): Setor de Impressão → impressão de rótulos via API createLabel
- Devolve para (se rejeitado): Geração de REQ — pedido volta a Pago para correção
- Alertas de data consumidos por: Triagem Técnica — Farm. Triagista é quem questiona datas com alerta
- JSON consumido por: Impressão de rótulos, Conferências de Produção, Triagem Técnica (como referência)
- Mapa de responsabilidades: Mapa de Responsabilidades por Etapa
- Índice de mecanismos de sistema: referencia-sistema-erp — este processo é a fonte canônica para: webhook Ag. Impressão (#2), API createLabel (#4), JSON consolidado (#5), documentos no PV (#6)
- Automação: contexto-print-service-neofarma — Print Service que implementa a impressão dos documentos gerados por este processo (rótulos via Ghostscript, fichas via PAD, fita via ESC/POS)
Histórico de evolução
| Data | Mudança | Motivação |
|---|---|---|
| 2026-04-02 | Criação do documento com estrutura do JSON consolidado, critérios de aceitação/rejeição, e fluxo webhook→verificação→veredito | Sessão de arquitetura com João — definição da conferência automática no ponto de cristalização |
| 2026-04-06 | Adicionada verificação de datas (retirada × previsão, datas entre dígitos) e horas (hora entre dígitos, hora × tipo de envio, esporádico :30). Campos envio e datas adicionados ao JSON. Novos critérios de bloqueio (hora) e alerta (data) | 2026-04-06-processos-sem-regras-datas-filtros-envio |
| 2026-04-06 | Reforçado que o JSON gera o PDF do rótulo (API createLabel) nesta etapa — momento da cristalização. Paciente OCR é fonte prioritária. Detalhados dois tipos de volta quando Triagem detecta problema: erro de dados → Pago, falta aviso → Ag. Impressão. Setor de Impressão como executor puro + autonomia para adicionar avisos quando Triagem devolve | Detalhamento com João — formação do rótulo e fluxos de volta |
| 2026-04-06 | Adicionada lista completa dos 5 documentos disponíveis no PV após Ag. Impressão: prescrição, validação de assinatura, comando de produção (ficha de pesagem), rótulos (quantidade = itens no PV), registro de entrega (se flag). Setor de Impressão imprime todos. Conf. 2 como fallback para registro de entrega | Detalhamento com João — documentos do Setor de Impressão |