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:

  1. OCR — dados da prescrição digitalizada: prescritor, paciente, composição por fórmula, posologia, base/veículo, volume, quantidade de frascos
  2. Pedido de venda (ERP de vendas) — cliente, produtos comprados, quantidades, preços, endereço de entrega, tipo de envio, observações
  3. 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çãoFonte AFonte BRegraEfeito
Hora entre dígitos da REQREQ dígito 1REQ dígito NTodas as horas iguaisRejeita se diferente
Hora × tipo de envioREQ horaPV tipo de envioHora consistente com tipoRejeita se inconsistente (hora :00)
Hora × tipo de envio (esporádico)REQ horaPV tipo de envioNão valida se hora :30 (esporádico/extra por definição)

Regras de data (alertam mas não bloqueiam):

VerificaçãoFonte AFonte BRegraEfeito
Data de retirada × previsãoREQ data retiradaPV previsão de produçãoRetirada ≥ Previsão⚠️ Alerta se retirada < previsão (requer prioridade da gerente)
Data de retirada × previsãoREQ data retiradaPV previsão de produçãoRetirada > Previsãoℹ️ Info — pedido será produzido depois do calculado (divergência de filtros ERP × produção)
Data entre dígitos da REQREQ dígito 1REQ dígito NTodas as datas iguaisRejeita 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:

IndicadorSignificadoEfeito no veredito
Confere entre as fontesNenhum — campo aceito
ℹ️Informação em uma fonte só, sem correspondente nas outrasAceito (esperado para excipientes, conservantes)
⚠️Divergência que pode ser legítima ou erroAceito com flag — campo entra no JSON com divergencia: true
Inconsistência claraRejeita 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:

CampoFonte prioritáriaFallbackJustificativa
Nome do pacienteOCRREQ (por produto)OCR é o documento fundacional
PrescritorOCRREQ (por produto)OCR tem dados completos (nome + conselho)
ComposiçãoREQREQ tem composição técnica detalhada (items[])
ConcentraçãoREQOCRREQ tem valores exatos; OCR pode ter arredondamento
VolumeREQOCRREQ tem volume.volume e volume.contain separados
Forma farmacêuticaREQCódigo padronizado do ERP
Base/veículoREQOCRREQ tem nome técnico; OCR tem nome genérico
PosologiaOCRREQOCR é mais completo; REQ pode truncar
PreçoPedidoREQ (charge)Pedido é o registro comercial oficial
EndereçoPedidoChat (se divergir, flag)Pedido é o registro oficial
ObservaçõesPedido + ChatAmbas 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.

#DocumentoFonteGeraçãoQuantidade
1Arquivo da prescriçãoOCR (receita digitalizada)Já existia no PV (anexada pelo Atendente)1 por pedido
2Validação da assinatura da prescriçãoSistema de validaçãoGerada a partir da assinatura digital do prescritor1 por pedido
3Comando de produção (ficha de pesagem)REQGerado a partir dos dados da REQ1 por pedido (cobre todos os dígitos)
4RótulosJSON consolidado (API createLabel)Gerados automaticamente — cada dígito da REQ gera rótulo(s) na quantidade de itens do produto no PVN rótulos (1 por unidade de cada produto)
5Registro de entrega (se aplicável)Sistema (botão do avião)Gerado automaticamente para produtos com flag “registro de entrega” no PV1 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

  1. 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.
  2. 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.

  3. 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).

  4. Expedição — O registro de entrega (quando existe) acompanha o pacote até a transportadora.

Resumo RACI

FaseR (Executa)A (Presta contas)C (Consulta)I (Informado)
1. Captura de dadosAgente verificador (auto)
2. Conferência 2 níveisAgente verificador (auto)
3. VereditoAgente 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

Histórico de evolução

DataMudançaMotivação
2026-04-02Criação do documento com estrutura do JSON consolidado, critérios de aceitação/rejeição, e fluxo webhook→verificação→vereditoSessão de arquitetura com João — definição da conferência automática no ponto de cristalização
2026-04-06Adicionada 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-06Reforç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 devolveDetalhamento com João — formação do rótulo e fluxos de volta
2026-04-06Adicionada 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 entregaDetalhamento com João — documentos do Setor de Impressão