4. Modelo de Dados — Entrada

Este capítulo detalha a estrutura esperada dos dados que você deve enviar para cada endpoint.


O Que Atualizou

16/09/2026 — Venda Diária (ErpDailySales)

Endpoints: POST /erp-data/daily-sale, PUT /erp-data/daily-sale e suas versões em lote (/batch).

Campo Tipo Obrigatoriedade Validação O que é
sellDateTimeUtc datetime Obrigatório ISO 8601 em UTC, terminado em Z Data e hora reais da venda
erpId String Obrigatório Máx. 128 caracteres Identificador da linha de venda no ERP
invoiceNumber String Opcional Máx. 64 caracteres Número da nota fiscal da venda
transactionCode String Opcional Máx. 64 caracteres Código da transação/cupom no ERP

date deixou de ser aceito

O campo date foi substituído por sellDateTimeUtc. Registro enviado com date é recusado com HTTP 400 e a mensagem O campo 'date' foi substituído por 'sellDateTimeUtc'.

Orientações de envio:

  • sellDateTimeUtc: o momento em que a venda ocorreu, com hora, minuto e segundo, em UTC. O envio apenas da data, com o horário fixo em 00:00:00, deixa de ser o formato esperado.
  • Converter do horário de Brasília (UTC−3) somando 3 horas. Quando a soma passa da meia-noite, a data em UTC é a do dia seguinte — e esse é o comportamento correto. Venda às 22:30 de 11/09 em Brasília vai como "2026-09-12T01:30:00Z".
  • Todas as linhas da mesma compra trazem o mesmo sellDateTimeUtc, invoiceNumber e transactionCode.
  • erpId: informado em todos os registros de venda diária, com um valor próprio por linha de venda.
  • invoiceNumber e transactionCode: informados sempre que a venda possuir esses dados.

Regras de preenchimento em 4.3 Estrutura de Venda Diária.


4.1 Estrutura de Produto (ErpProduct)

Campos Obrigatórios

Campo Tipo Tamanho Descrição Exemplo
erpId Long (Número inteiro) até 19 dígitos ID único do produto no seu ERP 12345
ncmCode String até 8 caracteres Código NCM do produto "84733090"
status String até 50 caracteres Status do produto (Active, Inactive, etc.) "Active"
description String até 500 caracteres Nome/descrição do produto "Dipirona 500mg Cápsulas"

Campos Opcionais (Altamente Recomendados)

Campo Tipo Tamanho Descrição Exemplo
ean String até 13 caracteres Código de barras EAN "7896045000001"
brand String até 100 caracteres Marca do produto "Genérico"
sku String até 100 caracteres Identificador SKU interno "SKU-DIPO-500-001"
internalDescription String até 500 caracteres Descrição interna "Analgésico - Genérico"
healthRegistration String até 50 caracteres Número do registro de saúde "61541"
manufacturer String até 200 caracteres Nome do fabricante "Laboratório Exemplo"
manufacturerCnpj String 14 caracteres (com ou sem formatação) CNPJ do fabricante "12.345.678/0001-90"

Campos Opcionais (Complementares)

Campo Tipo Tamanho Descrição Exemplo
webName String até 200 caracteres Nome para exibição na web "Dipirona 500mg"
specification String até 1000 caracteres Especificações técnicas "Cápsulas de 500mg, frasco com 20"
metaDescription String até 500 caracteres Meta-descrição para SEO "Compre Dipirona 500mg online"
weightGr Decimal até 99.999,99 Peso em gramas 25.50
lengthCm Decimal até 99.999,99 Comprimento em cm 10.0
widthCm Decimal até 99.999,99 Largura em cm 5.0
heightCm Decimal até 99.999,99 Altura em cm 15.0
ipi Boolean --- Sujeito a IPI? true
dun String até 14 caracteres Código DUN "2345678900018"
purchaseGroup String até 100 caracteres Grupo de compra "Analgésicos"
purchaseStatus String até 50 caracteres Status para compra "Available"
taxClassification String até 50 caracteres Classificação fiscal "ClassA"
boxQuantity String até 50 caracteres Quantidade por caixa "20"
billingQuantity String até 50 caracteres Quantidade para faturamento "1"
activePrinciple String até 200 caracteres Princípio ativo "Dipirona Monoidratada"
healthRegistrationReason String até 200 caracteres Motivo do registro "Medicamento"
keywords String até 500 caracteres Palavras-chave para busca "dor, febre, analgésico"
indication String até 1000 caracteres Indicações de uso "Dor leve a moderada, febre"
contraindication String até 1000 caracteres Contra-indicações "Alergia à dipirona"
medicalPrescriptionType String até 50 caracteres Tipo de prescrição "None" ou "Required"
continuousUse Boolean --- Medicamento de uso contínuo? false
controlledSale Boolean --- Venda controlada? false
minimumPurchaseMultiple Integer até 9.999 Múltiplo mínimo de compra 1

Exemplo Válido — Mínimo

{
  "erpId": 12345,
  "ncmCode": "84733090",
  "status": "Active",
  "description": "Dipirona 500mg Cápsulas"
}

Exemplo Válido — Completo

{
  "erpId": 12345,
  "ncmCode": "84733090",
  "status": "Active",
  "ean": "7896045000001",
  "description": "Dipirona 500mg Cápsulas",
  "internalDescription": "Genérico - Analgésico",
  "webName": "Dipirona 500mg",
  "specification": "Cápsulas de 500mg, frasco com 20",
  "metaDescription": "Compre Dipirona 500mg online",
  "brand": "Genérico",
  "sku": "SKU-DIPO-500-001",
  "healthRegistration": "61541",
  "manufacturer": "Laboratório Exemplo",
  "manufacturerCnpj": "12.345.678/0001-90",
  "weightGr": 25.5,
  "lengthCm": 10.0,
  "widthCm": 5.0,
  "heightCm": 15.0,
  "ipi": false,
  "purchaseGroup": "Analgésicos",
  "purchaseStatus": "Available",
  "activePrinciple": "Dipirona Monoidratada",
  "indication": "Dor leve a moderada, febre",
  "contraindication": "Alergia à dipirona",
  "medicalPrescriptionType": "None",
  "continuousUse": false,
  "controlledSale": false,
  "minimumPurchaseMultiple": 1
}

Exemplos Inválidos

❌ Exemplo 1: Campo Obrigatório Ausente

{
  "erpId": 12345,
  "ncmCode": "84733090",
  "status": "Active"
  // Faltando: description
}

Erro esperado:

Field 'description' is required

❌ Exemplo 2: Tipo de Dado Incorreto

{
  "erpId": "não é um número",
  "ncmCode": "84733090",
  "status": "Active",
  "description": "Dipirona 500mg"
}

Erro esperado:

Field 'erpId' must be a number

❌ Exemplo 3: Campo Vazio

{
  "erpId": 12345,
  "ncmCode": "",
  "status": "Active",
  "description": "Dipirona 500mg"
}

Erro esperado:

Field 'ncmCode' must not be empty

❌ Exemplo 4: Tamanho Máximo Excedido

{
  "erpId": 12345,
  "ncmCode": "84733090123456789", // Máximo 8 caracteres
  "status": "Active",
  "description": "Dipirona 500mg"
}

Erro esperado:

Field 'ncmCode' must not exceed 8 characters

4.2 Estrutura de Estoque (ErpStock)

Campos Obrigatórios

Campo Tipo Descrição Exemplo
company Decimal Código da empresa 1
companyName String Nome da empresa "Loja Centro"
address String Endereço da loja "Rua Principal, 100"
productDescription String Descrição do produto "Dipirona 500mg"

Campos Recomendados

Campo Tipo Descrição Exemplo
currentStock Decimal Quantidade em estoque 500.00
warehouseTransit Decimal Quantidade em trânsito 100.00
distributionCenterStock Decimal Estoque no CD 2000.00
brand String Marca "Genérico"
currentAbcCurve String Classificação ABC "A"
cnpj String CNPJ da loja "12.345.678/0001-90"
venancioBarcodeCode String Código de barras "7896045000001"

Exemplo Válido

{
  "company": 1,
  "companyName": "Loja Centro",
  "address": "Rua Principal, 100",
  "productDescription": "Dipirona 500mg",
  "currentStock": 500.0,
  "warehouseTransit": 100.0,
  "distributionCenterStock": 2000.0,
  "brand": "Genérico",
  "currentAbcCurve": "A",
  "cnpj": "12.345.678/0001-90"
}

4.3 Estrutura de Venda Diária (ErpDailySales)

Campos Obrigatórios

Campo Tipo Descrição Validação Exemplo
erpId String Identificador da linha de venda no ERP Máx. 128 caracteres "CUPOM-100234-LINHA-1"
erpProductId String ID do produto no ERP Deve existir "12345"
erpStoreId String ID da loja no ERP Deve existir "1001"
sellDateTimeUtc DateTime Data e hora reais da venda Deve ser UTC "2026-09-11T17:32:10Z"
quantity Decimal Quantidade vendida > 0 15.00
totalSellValue Decimal Valor total da venda >= 0 125.50

Campos Opcionais

Campo Tipo Descrição Validação Exemplo
invoiceNumber String Número da nota fiscal da venda Máx. 64 caracteres "000123456"
transactionCode String Código da transação/cupom no ERP Máx. 64 caracteres "CUPOM-100234"
origin String Origem da venda Máx. 128 caracteres "Balcão"
deliveryMethod String Método de entrega Máx. 64 caracteres "Retirada"

O campo erpId

Identificador da linha de venda no ERP (o item do cupom ou da transação). Obrigatório em todos os registros de venda diária.

  • Use o identificador da linha que o próprio ERP já gera. Não gere o valor a partir de outros campos do payload (por exemplo, um hash de produto + loja + data).
  • Cada linha de venda tem seu próprio erpId. Uma compra com três produtos gera três registros, com três erpId diferentes.
  • O valor deve ser estável: a mesma linha de venda tem sempre o mesmo erpId, em qualquer envio.
  • Correções: para corrigir uma venda já enviada, reenvie o registro com o mesmo erpId e os valores corretos. O registro anterior é substituído.

Os campos invoiceNumber e transactionCode

Identificam a compra à qual a linha de venda pertence. Opcionais.

Campo O que enviar
invoiceNumber Número da nota fiscal da venda.
transactionCode Código da transação ou do cupom no ERP.
  • Todas as linhas da mesma compra devem trazer o mesmo invoiceNumber e/ou transactionCode.
  • Envie os dois quando a venda tiver os dois. Se tiver só um, envie só esse.
  • Envie o valor exatamente como está no ERP. Máscara, série, zeros à esquerda e a chave de acesso de 44 dígitos são aceitos, desde que caibam em 64 caracteres.
  • Não gere esses valores a partir de outros campos do payload.
  • Esses campos não substituem o erpId: erpId identifica a linha e invoiceNumber / transactionCode identificam a compra.

Importante: Tratamento de Data

Mudança de 16/09/2026. O campo date passou a se chamar sellDateTimeUtc e o nome antigo deixou de ser aceito — payload com date recebe HTTP 400 com a mensagem O campo 'date' foi substituído por 'sellDateTimeUtc'. Mudou também o conteúdo: espera-se o instante real da venda (hora, minuto e segundo), e não mais o dia com 00:00:00Z.

⚠️ CRÍTICO PARA POSTGRESQL

A data DEVE estar em formato ISO 8601 com timezone UTC:

✅ Formatos Válidos:

2026-09-11T17:32:10Z
2026-09-11T17:32:10.250Z

❌ Formatos Inválidos:

2026-09-11                 // Sem hora
17:32:10                   // Sem data
2026-09-11T17:32:10        // Sem Z (timezone)
2026-09-11T14:32:10-03:00  // Fuso local; converter para UTC
11/09/2026 14:32:10        // Fora do padrão ISO 8601

Conversão do horário de Brasília (UTC−3): somar 3 horas. Venda às 22:30 de 11/09 em Brasília vai como "2026-09-12T01:30:00Z" — dia seguinte em UTC, e isso está correto.

Exemplo Válido

{
  "erpId": "CUPOM-100234-LINHA-1",
  "erpProductId": "12345",
  "erpStoreId": "1001",
  "sellDateTimeUtc": "2026-09-11T17:32:10Z",
  "quantity": 15.0,
  "totalSellValue": 125.5,
  "invoiceNumber": "000123456",
  "transactionCode": "CUPOM-100234",
  "origin": "Balcão",
  "deliveryMethod": "Retirada"
}

Exemplo Inválido — Data Sem Timezone

{
  "erpId": "CUPOM-100234-LINHA-1",
  "erpProductId": "12345",
  "erpStoreId": "1001",
  "sellDateTimeUtc": "2026-09-11T17:32:10", // ❌ Faltando Z
  "quantity": 15.0,
  "totalSellValue": 125.5
}

Erro esperado:

Invalid DateTime format. Must be UTC with Z suffix: YYYY-MM-DDTHH:mm:ssZ

4.4 Estrutura de Loja (ErpStore)

Campos Obrigatórios

Campo Tipo Descrição Exemplo
erpId String ID da loja no ERP "1001"
title String Nome da loja "Farmácia Centro"

Campos Recomendados

Campo Tipo Descrição Exemplo
taxId String CNPJ da loja "12.345.678/0001-90"
stateRegistration String Inscrição Estadual "123.456.789.012"
zipCode String CEP "01234-567"
address String Logradouro "Rua Principal"
number String Número "100"
complement String Complemento "Próximo à estação"
neighborhood String Bairro (máx. 128 caracteres) "Centro"
city String Cidade (máx. 128 caracteres) "São Paulo"
state String UF, sigla de 2 letras "SP"

Campos de Características

Campo Tipo Descrição Exemplo
performsInjection Boolean Realiza injeções? true
sellsControlled Boolean Vende controlados? false
hasPopularFarmacy Boolean Farmácia Popular? true
storeType String Tipo de loja "Popular"
storeSize String Tamanho (P, M, G) "M"

Campos de Funcionamento

Campo Tipo Descrição Formato
weekdayHours String Horário seg-sex "09:00-20:00"
saturdayHours String Horário sábado "09:00-18:00"
sundayHours String Horário domingo "10:00-16:00"
openingDate DateTime Data de abertura "2020-01-15T00:00:00Z"
isActive Boolean Loja ativa? true

Exemplo Válido

{
  "erpId": "1001",
  "title": "Farmácia Centro",
  "taxId": "12.345.678/0001-90",
  "stateRegistration": "123.456.789.012",
  "zipCode": "01234-567",
  "address": "Rua Principal",
  "number": "100",
  "complement": "Próximo à estação",
  "neighborhood": "Centro",
  "city": "São Paulo",
  "state": "SP",
  "performsInjection": true,
  "sellsControlled": false,
  "hasPopularFarmacy": true,
  "storeType": "Popular",
  "storeSize": "M",
  "weekdayHours": "09:00-20:00",
  "saturdayHours": "09:00-18:00",
  "sundayHours": "10:00-16:00",
  "openingDate": "2020-01-15T00:00:00Z",
  "isActive": true
}

4.5 Estrutura de Fornecedor (ErpSupplier)

Campos Típicos

Campo Tipo Descrição Exemplo
erpId String ID do fornecedor "5001"
name String Nome do fornecedor "Laboratório Exemplo"
cnpj String CNPJ "98.765.432/0001-11"
address String Endereço "Av. Paulista, 1000"
stateRegistration String IE "987.654.321.012"

4.6 Estrutura de Venda Mensal (ErpMonthlySales)

Similar à Venda Diária, mas com data agregada:

Campo Tipo Descrição Exemplo
erpProductId String ID do produto "12345"
erpStoreId String ID da loja "1001"
month DateTime Mês da venda "2024-12-01T00:00:00Z"
quantity Decimal Quantidade vendida 450.00
totalSellValue Decimal Valor total 3750.00

4.7 Validações Gerais Aplicadas

Validações de Tipo

✓ String → Texto
✓ Decimal → Números com vírgula (0.00)
✓ Boolean → true ou false
✓ DateTime → ISO 8601 com Z
✗ Qualquer outro tipo → Erro 400

Validações de Tamanho

✓ Campo com até 50 caracteres → Aceita de 0-50
✗ Campo com até 50 caracteres → Rejeita > 50
✓ Campo obrigatório → Não pode ser vazio
✗ Campo obrigatório → Se vazio, erro

Validações de Formato

✓ NCM: 8 caracteres numéricos
✓ EAN: 13 caracteres (com ou sem dígito verificador)
✓ CNPJ: 14 caracteres (com ou sem formatação)
✓ CEP: 8 caracteres (com ou sem hífen)
✓ Data: ISO 8601 UTC com Z

Checklist de Dados — Antes de Enviar

  • [ ] Todos os campos obrigatórios estão preenchidos?
  • [ ] Nenhum campo obrigatório está vazio ou null?
  • [ ] Números estão em formato decimal (ex: 123.45)?
  • [ ] Datas estão no formato UTC ISO 8601 com Z?
  • [ ] Strings não excedem o tamanho máximo?
  • [ ] Booleanos estão como true/false (não "1"/"0")?
  • [ ] Códigos (NCM, EAN, CNPJ) têm o tamanho correto?
  • [ ] Nenhum caractere especial indevido nas strings?

Próxima Seção

5. Modelo de Dados — Saída (Sucesso)