# Estoque

Movimentação e consulta de saldo. O estoque tem três visões: o que **existe** fisicamente, o que está **reservado** em carrinhos/pedidos abertos, e o que sobra **disponível** para nova venda.

> Pré-requisitos: leia [Produtos: visão geral](/guia/produtos). O produto precisa existir antes de receber estoque; a rota é por `productId`.

---

## Conceitos

| Campo | O que é |
|---|---|
| `quantity` | Estoque físico total na sua loja. |
| `reserved_quantity` | Já comprometido em carrinhos/pedidos em aberto. |
| `available_quantity` | O que sobra pra venda: `quantity - reserved_quantity`. |

**Regra:** o catálogo respeita o `available_quantity`. Se ele zera, o produto deixa de aparecer pra novas compras, mesmo que ainda exista fisicamente.

O objeto que `GET /products/{id}/stock` devolve — total consolidado + saldo por localização:

```jsonc
{
  "total": 150,                // soma das quantidades em todos os locais
  "stocks": [                  // ← saldo por localização
    {
      "id": 321,               // ID do registro de saldo
      "product_sku": {…},      // resumo do produto dono do saldo
      "location_stock": {…},   // a localização deste saldo
      "quantity": 100,         // físico
      "reserved_quantity": 5,  // reservado em pedidos abertos
      "available_quantity": 95 // o que sobra pra venda
    }
  ],
  "locations": [{…}]           // metadados dos locais (name, status, location_type…)
}
```

### Tipos de movimentação

A rota de movimentação aceita 3 modos, controlados pelas flags booleanas `increment` e `decrement`:

| Flags enviadas | Efeito sobre `quantity` |
|---|---|
| nenhuma | Sobrescreve com o valor enviado. Útil pra **acerto de inventário**. |
| `increment: true` | Soma. Útil pra **entrada de fornecedor**. |
| `decrement: true` | Subtrai. Útil pra **baixa manual** (perda, avaria, venda fora do canal). |

Mandar as duas flags juntas é recusado com `400`.

> Os 3 modos só mexem em `quantity` — e você pode estar se perguntando como ajustar o `reserved_quantity`. A resposta é: você não precisa. Ele é cuidado pela plataforma, que reserva e libera saldo sozinha conforme os pedidos abrem e fecham. Isso evita que duas vendas simultâneas briguem pela mesma unidade, então deixe essa conta com a gente e foque só no estoque físico.

---

## Consultar saldo

<a class="api-route" href="/reference/produtos#tag/estoque-de-produtos/GET/api/products/{product_id}/stock"><span class="api-method api-method-get">GET</span><span class="api-path">/api/products/{id}/stock</span></a>

```json
{
  "data": {
    "total": 150,
    "stocks": [
      {
        "id": 321,
        "product_sku": {
          "id": "01H81AV32307PVBSV4RXF15EK9",
          "name": "Caneta Esferográfica Azul",
          "sku": "CAN-AZ-01"
        },
        "location_stock": {
          "location_id": "01H81AV32307PVBSV4RXF15LOC",
          "store_id": 42,
          "name": "Matriz - São Paulo",
          "status": "available",
          "location_type": "seller_location",
          "allows_pickup": false,
          "allows_production": false
        },
        "quantity": 100,
        "reserved_quantity": 5,
        "available_quantity": 95
      }
    ],
    "locations": [
      {
        "location_id": "01H81AV32307PVBSV4RXF15LOC",
        "store_id": 42,
        "name": "Matriz - São Paulo",
        "status": "available",
        "location_type": "seller_location",
        "allows_pickup": false,
        "allows_production": false
      }
    ]
  }
}
```

> No exemplo, o `product_sku` aparece resumido — na prática ele vem com o cadastro completo do produto (preços, thumbnail, dimensões…).

---

## Movimentar

<a class="api-route" href="/reference/produtos#tag/estoque-de-produtos/POST/api/products/{product_id}/stock"><span class="api-method api-method-post">POST</span><span class="api-path">/api/products/{id}/stock</span></a>

O `location_id` é **obrigatório** — diz em qual local o saldo se move. Sem flag nenhuma, o valor enviado **sobrescreve** a quantidade:

```json
{
  "location_id": "01H81AV32307PVBSV4RXF15LOC",
  "quantity": 150
}
```

### Exemplos por cenário

**Recebi 40 unidades do fornecedor:**

```json
{
  "location_id": "01H81AV32307PVBSV4RXF15LOC",
  "quantity": 40,
  "increment": true
}
```

**Inventário deu 95 (era 100):**

```json
{
  "location_id": "01H81AV32307PVBSV4RXF15LOC",
  "quantity": 95
}
```

**Avaria, baixar 3:**

```json
{
  "location_id": "01H81AV32307PVBSV4RXF15LOC",
  "quantity": 3,
  "decrement": true
}
```
