Skip to main content

Visão geral

O módulo de estoque do OmniDom é multi-depósito. Cada registro de estoque é a combinação produto + depósito (warehouse). O ciclo de vida de cada unidade no estoque:
Disponível (available)

    ├─ reserve()  →  Reservado (reserved)
    │                    │
    │                    ├─ confirm()  →  Venda concluída (deduzido)
    │                    └─ release()  →  Disponível novamente

    └─ adjustStock()  →  Ajuste manual (entrada ou saída)

Depósitos (Warehouses)

Um depósito representa um local físico ou virtual onde o estoque é armazenado.

Listar depósitos

GET /warehouses
Query params:
ParâmetroTipoDescrição
isActivebooleanFiltrar por status
searchstringBusca por nome ou código

Criar depósito

POST /warehouses
Content-Type: application/json
Body:
{
  "name": "Galpão Principal",
  "code": "GP-01",
  "address": "Rua das Flores, 100",
  "isDefault": false
}
CampoTipoObrig.Descrição
namestringNome do depósito
codestringCódigo único por tenant
addressstringEndereço físico
isDefaultbooleanNovo depósito já como padrão?
Erro 409: Código duplicado no mesmo tenant.

Detalhar depósito

GET /warehouses/:id
Retorna os detalhes com a contagem de itens distintos em estoque.

Atualizar depósito

PATCH /warehouses/:id
Content-Type: application/json

Definir depósito padrão

PATCH /warehouses/:id/set-default
O depósito padrão é usado em operações que não especificam warehouseId. Erro 400: Depósito inativo não pode ser definido como padrão.

Excluir depósito

DELETE /warehouses/:id
Soft delete. Não é possível excluir o depósito padrão ou um depósito com estoque positivo.

Consulta de estoque

Listar estoque com filtros

GET /inventory
Query params:
ParâmetroTipoDescrição
warehouseIdUUIDFiltrar por depósito
productIdUUIDFiltrar por produto
stockStatusstringlow, out, ok
pagenumberPaginação
limitnumberRegistros por página

Estoque de um produto por depósito

GET /inventory/product/:productId
Retorna o breakdown completo por depósito: quantidade disponível, reservada e física. Resposta:
{
  "totalAvailable": 42,
  "totalReserved": 8,
  "totalPhysical": 50,
  "warehousesCount": 2,
  "stocks": [
    {
      "warehouseId": "uuid-galpao-a",
      "warehouseName": "Galpão A",
      "available": 30,
      "reserved": 5,
      "physical": 35
    },
    {
      "warehouseId": "uuid-galpao-b",
      "warehouseName": "Galpão B",
      "available": 12,
      "reserved": 3,
      "physical": 15
    }
  ]
}

Resumo de estoque (só totais)

GET /inventory/product/:productId/summary
Versão leve sem breakdown por depósito. Use quando precisar apenas dos totais.

Produtos com estoque baixo

GET /inventory/low-stock?limit=10
Retorna produtos com available < minStock.

Ajustes de estoque

Ajustar estoque manualmente

PATCH /inventory/product/:productId/adjust
Content-Type: application/json
Body:
{
  "quantity": -5,
  "reason": "Quebra/perda identificada",
  "warehouseId": "uuid-do-deposito"
}
CampoTipoObrig.Descrição
quantitynumberPositivo = entrada, negativo = saída. Não pode ser 0.
reasonstringMotivo do ajuste (auditoria)
warehouseIdUUIDDepósito alvo. Usa o padrão se omitido.

Reservar estoque

PATCH /inventory/product/:productId/reserve/:quantity
Transfere unidades de available para reserved. Usado ao criar um pedido. Erro 400: Estoque disponível insuficiente.

Confirmar venda

PATCH /inventory/product/:productId/confirm/:quantity
Deduz as unidades do reserved (a venda foi concluída). O estoque físico diminui.

Liberar reserva

PATCH /inventory/product/:productId/release/:quantity
Retorna as unidades do reserved para available. Usado ao cancelar um pedido.

Ações em massa

POST /inventory/bulk-action
Content-Type: application/json
Suporta três tipos de ação sobre múltiplos produtos:
AçãoDescrição
zeroZerar estoque (ajuste para 0)
set-minimumDefinir estoque mínimo em massa
transferTransferir estoque de um depósito para outro

Transferências entre depósitos

Listar transferências

GET /inventory/transfers
Query params: fromWarehouseId, toWarehouseId, productId, status, page, limit.

Criar transferência

POST /inventory/transfers
Content-Type: application/json
Body:
{
  "productId": "uuid-do-produto",
  "fromWarehouseId": "uuid-origem",
  "toWarehouseId": "uuid-destino",
  "quantity": 10,
  "notes": "Redistribuição para campanha"
}
Erro 400: Estoque insuficiente no depósito de origem.

Cancelar transferência

PATCH /inventory/transfers/:id/cancel
Só é possível cancelar transferências com status PENDING.

Entradas de estoque

O sub-módulo de entradas registra o histórico de como o estoque foi adicionado: manualmente, via NF-e ou via CSV.

Listar entradas

GET /inventory/entries

Entrada manual

POST /inventory/entries/manual
Content-Type: application/json
Body:
{
  "productId": "uuid",
  "warehouseId": "uuid",
  "quantity": 50,
  "unitCost": 12.50,
  "notes": "Compra de emergência"
}

Entrada via NF-e

POST /inventory/entries/nfe
Content-Type: application/json
Body:
{
  "xmlContent": "<nfeProc>...</nfeProc>",
  "warehouseId": "uuid"
}
Erro 409: NF-e com a mesma chave de acesso já importada.
Para upload de arquivos XML em lote com fluxo de preview e confirmação, use o módulo de Importação NF-e.

Importação em massa via CSV

POST /inventory/entries/csv
Content-Type: application/json
Body:
{
  "csvContent": "sku,quantity,unitCost,warehouseId\nCAM-BCO-P,50,12.50,uuid-deposito\n..."
}
Download do template:
GET /inventory/entries/csv-template

Balanço físico (Inventory Count)

Registra uma contagem física e gera um ajuste de reconciliação automático.
POST /inventory/product/:productId/count
Content-Type: application/json
Body:
{
  "warehouseId": "uuid",
  "countedQuantity": 47,
  "notes": "Balanço semestral"
}
O sistema calcula a diferença entre o estoque no sistema e a quantidade contada e cria um ajuste com o motivo PHYSICAL_COUNT.

Exportar estoque para CSV

GET /inventory/export
Aceita os mesmos query params do GET /inventory. Retorna um arquivo .csv para download.
Content-Type: text/csv
Content-Disposition: attachment; filename="estoque.csv"

Dashboard de estoque

KPIs gerais

GET /inventory/dashboard/summary?warehouseId=uuid
Retorna totais de SKUs, unidades disponíveis, reservadas e valor estimado.

Produtos com estoque baixo

GET /inventory/dashboard/low-stock?limit=20&warehouseId=uuid

Produtos sem estoque

GET /inventory/dashboard/out-of-stock?limit=20&warehouseId=uuid

Movimentações recentes

GET /inventory/dashboard/movements?limit=20&productId=uuid
Timeline das últimas entradas, saídas e ajustes.

Estoque por depósito

GET /inventory/dashboard/by-warehouse
Visão consolidada do estoque agrupado por depósito.

Valor do estoque

GET /inventory/dashboard/stock-value?warehouseId=uuid
Retorna o valor total e os top produtos com maior valor em estoque.

Giro de estoque

GET /inventory/dashboard/turnover?days=30
Calcula quantas vezes o estoque girou no período informado.

Cobertura de estoque

GET /inventory/dashboard/coverage?days=30
Estima em quantos dias o estoque atual será esgotado com base no histórico de saídas.