> ## Documentation Index
> Fetch the complete documentation index at: https://docs.domsoftware.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Gestão de Estoque

> Depósitos, ajustes, transferências, entradas e dashboard de estoque no OmniDom.

## 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

```http theme={null}
GET /warehouses
```

**Query params:**

| Parâmetro  | Tipo    | Descrição                |
| ---------- | ------- | ------------------------ |
| `isActive` | boolean | Filtrar por status       |
| `search`   | string  | Busca por nome ou código |

***

### Criar depósito

```http theme={null}
POST /warehouses
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "name": "Galpão Principal",
  "code": "GP-01",
  "address": "Rua das Flores, 100",
  "isDefault": false
}
```

| Campo       | Tipo    | Obrig. | Descrição                     |
| ----------- | ------- | ------ | ----------------------------- |
| `name`      | string  | ✅      | Nome do depósito              |
| `code`      | string  | ✅      | Código único por tenant       |
| `address`   | string  |        | Endereço físico               |
| `isDefault` | boolean |        | Novo depósito já como padrão? |

**Erro `409`:** Código duplicado no mesmo tenant.

***

### Detalhar depósito

```http theme={null}
GET /warehouses/:id
```

Retorna os detalhes com a contagem de itens distintos em estoque.

***

### Atualizar depósito

```http theme={null}
PATCH /warehouses/:id
Content-Type: application/json
```

***

### Definir depósito padrão

```http theme={null}
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

```http theme={null}
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

```http theme={null}
GET /inventory
```

**Query params:**

| Parâmetro     | Tipo   | Descrição            |
| ------------- | ------ | -------------------- |
| `warehouseId` | UUID   | Filtrar por depósito |
| `productId`   | UUID   | Filtrar por produto  |
| `stockStatus` | string | `low`, `out`, `ok`   |
| `page`        | number | Paginação            |
| `limit`       | number | Registros por página |

***

### Estoque de um produto por depósito

```http theme={null}
GET /inventory/product/:productId
```

Retorna o breakdown completo por depósito: quantidade disponível, reservada e física.

**Resposta:**

```json theme={null}
{
  "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)

```http theme={null}
GET /inventory/product/:productId/summary
```

Versão leve sem breakdown por depósito. Use quando precisar apenas dos totais.

***

### Produtos com estoque baixo

```http theme={null}
GET /inventory/low-stock?limit=10
```

Retorna produtos com `available < minStock`.

***

## Ajustes de estoque

### Ajustar estoque manualmente

```http theme={null}
PATCH /inventory/product/:productId/adjust
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "quantity": -5,
  "reason": "Quebra/perda identificada",
  "warehouseId": "uuid-do-deposito"
}
```

| Campo         | Tipo   | Obrig. | Descrição                                               |
| ------------- | ------ | ------ | ------------------------------------------------------- |
| `quantity`    | number | ✅      | Positivo = entrada, negativo = saída. Não pode ser `0`. |
| `reason`      | string | ✅      | Motivo do ajuste (auditoria)                            |
| `warehouseId` | UUID   |        | Depósito alvo. Usa o padrão se omitido.                 |

***

### Reservar estoque

```http theme={null}
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

```http theme={null}
PATCH /inventory/product/:productId/confirm/:quantity
```

Deduz as unidades do `reserved` (a venda foi concluída). O estoque físico diminui.

***

### Liberar reserva

```http theme={null}
PATCH /inventory/product/:productId/release/:quantity
```

Retorna as unidades do `reserved` para `available`. Usado ao cancelar um pedido.

***

## Ações em massa

```http theme={null}
POST /inventory/bulk-action
Content-Type: application/json
```

Suporta três tipos de ação sobre múltiplos produtos:

| Ação          | Descrição                                    |
| ------------- | -------------------------------------------- |
| `zero`        | Zerar estoque (ajuste para 0)                |
| `set-minimum` | Definir estoque mínimo em massa              |
| `transfer`    | Transferir estoque de um depósito para outro |

***

## Transferências entre depósitos

### Listar transferências

```http theme={null}
GET /inventory/transfers
```

**Query params:** `fromWarehouseId`, `toWarehouseId`, `productId`, `status`, `page`, `limit`.

***

### Criar transferência

```http theme={null}
POST /inventory/transfers
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "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

```http theme={null}
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

```http theme={null}
GET /inventory/entries
```

***

### Entrada manual

```http theme={null}
POST /inventory/entries/manual
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "productId": "uuid",
  "warehouseId": "uuid",
  "quantity": 50,
  "unitCost": 12.50,
  "notes": "Compra de emergência"
}
```

***

### Entrada via NF-e

```http theme={null}
POST /inventory/entries/nfe
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "xmlContent": "<nfeProc>...</nfeProc>",
  "warehouseId": "uuid"
}
```

**Erro `409`:** NF-e com a mesma chave de acesso já importada.

<Tip>
  Para upload de arquivos XML em lote com fluxo de preview e confirmação, use o [módulo de Importação NF-e](/omnidom/import).
</Tip>

***

### Importação em massa via CSV

```http theme={null}
POST /inventory/entries/csv
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "csvContent": "sku,quantity,unitCost,warehouseId\nCAM-BCO-P,50,12.50,uuid-deposito\n..."
}
```

**Download do template:**

```http theme={null}
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.

```http theme={null}
POST /inventory/product/:productId/count
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "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

```http theme={null}
GET /inventory/export
```

Aceita os mesmos query params do `GET /inventory`. Retorna um arquivo `.csv` para download.

```http theme={null}
Content-Type: text/csv
Content-Disposition: attachment; filename="estoque.csv"
```

***

## Dashboard de estoque

### KPIs gerais

```http theme={null}
GET /inventory/dashboard/summary?warehouseId=uuid
```

Retorna totais de SKUs, unidades disponíveis, reservadas e valor estimado.

***

### Produtos com estoque baixo

```http theme={null}
GET /inventory/dashboard/low-stock?limit=20&warehouseId=uuid
```

***

### Produtos sem estoque

```http theme={null}
GET /inventory/dashboard/out-of-stock?limit=20&warehouseId=uuid
```

***

### Movimentações recentes

```http theme={null}
GET /inventory/dashboard/movements?limit=20&productId=uuid
```

Timeline das últimas entradas, saídas e ajustes.

***

### Estoque por depósito

```http theme={null}
GET /inventory/dashboard/by-warehouse
```

Visão consolidada do estoque agrupado por depósito.

***

### Valor do estoque

```http theme={null}
GET /inventory/dashboard/stock-value?warehouseId=uuid
```

Retorna o valor total e os top produtos com maior valor em estoque.

***

### Giro de estoque

```http theme={null}
GET /inventory/dashboard/turnover?days=30
```

Calcula quantas vezes o estoque girou no período informado.

***

### Cobertura de estoque

```http theme={null}
GET /inventory/dashboard/coverage?days=30
```

Estima em quantos dias o estoque atual será esgotado com base no histórico de saídas.
