# Produtos (catálogo da empresa)

Cada empresa tem um **catálogo** de produtos: SKU → NCM, origem, GTIN e unidade. O catálogo é **opcional**, mas poupa trabalho: na emissão, o item que não informa `codigo_ncm`, `icms_origem` (e os demais dados do produto) usa o produto do catálogo com o mesmo `codigo_produto`. O que o item informa **sempre vence** o catálogo.

Se o item não informa e o catálogo também não tem, a API responde `422` apontando o campo (por exemplo `items.1.codigo_ncm`: "Informe codigo_ncm (ou cadastre o produto BONE-U no catálogo da empresa)").

| Método | Rota | Para quê |
|---|---|---|
| `GET` | `/empresas/{cnpj}/produtos` | listar (paginado; `?q=` busca SKU, descrição ou início do NCM) |
| `GET` | `/empresas/{cnpj}/produtos/{sku}` | detalhar |
| `PUT` | `/empresas/{cnpj}/produtos/{sku}` | criar ou substituir o produto do SKU |
| `DELETE` | `/empresas/{cnpj}/produtos/{sku}` | remover (`204`) |
| `POST` | `/empresas/{cnpj}/produtos/importacao` | importar vários de uma vez |

## Criar ou atualizar um produto

`PUT /empresas/{cnpj}/produtos/CAMISA-P` **cria** (`201`) ou **substitui** (`200`) o produto do SKU da URL. É idempotente: o seu ERP pode repetir o mesmo `PUT` à vontade, o que o torna o jeito natural de **sincronizar** o catálogo.

<!-- exemplo:produto sku=CAMISA-P -->
```json
{
  "descricao": "Camiseta basica algodao P",
  "ncm": "6109.10.00",
  "origem": 0,
  "unidade": "UN",
  "gtin": "7891000100103"
}
```

Resposta (o SKU identifica o produto; não há id numérico):

```json
{ "sku": "CAMISA-P", "descricao": "Camiseta basica algodao P", "ncm": "61091000", "cest": null, "origem": 0, "unidade": "UN", "gtin": "7891000100103", "producao_propria": false }
```

| Campo | Regra |
|---|---|
| `descricao` | obrigatória, até 120 caracteres |
| `ncm` | obrigatório, 8 dígitos (a máscara é removida) |
| `origem` | origem da mercadoria, 0 a 8. Padrão 0 (nacional). **Importados (1, 2, 3, 8...) mudam a alíquota interestadual**: informe certo |
| `unidade` | unidade comercial. Padrão `UN` |
| `cest` | 7 dígitos, para mercadorias sujeitas a substituição tributária |
| `gtin` | GTIN-8/12/13/14 com **dígito verificador válido** (a SEFAZ rejeita o inválido). Sem código de barras, omita |
| `producao_propria` | `true` se você fabrica o produto (CFOP x101); padrão `false` = revenda (CFOP x102) |
| `sku` | se vier no corpo, tem de ser igual ao da URL |

Campo desconhecido é recusado. O mesmo SKU pode existir em empresas diferentes, com dados diferentes.

> SKU com barra (`/`) não cabe na URL: cadastre-o pela importação.

## Importar vários de uma vez

`POST /empresas/{cnpj}/produtos/importacao` grava a lista inteira **ou nada**: se **uma** linha for inválida, nenhum produto é gravado e o erro aponta a linha, para você corrigir e reenviar. SKU que já existe é **atualizado**. Até **2000** produtos por chamada.

<!-- exemplo:importacao -->
```json
{
  "produtos": [
    { "sku": "CAMISA-M", "descricao": "Camiseta basica algodao M", "ncm": "61091000" },
    { "sku": "BONE-U", "descricao": "Bone aba curva", "ncm": "65050090", "origem": 0 }
  ]
}
```

Resposta `200`: `{ "criados": 2, "atualizados": 0 }`.

Com linha inválida, `422` e nada gravado (a "linha" é a posição na lista, começando em 1):

```json
{ "codigo": "requisicao_invalida", "mensagem": "Linha 2: O campo NCM deve ter 8 dígitos.",
  "erros": { "produtos": ["Linha 2: O campo NCM deve ter 8 dígitos."] } }
```

Você também pode enviar um **arquivo CSV** (até 1 MB) em `arquivo`, em `multipart/form-data`, com cabeçalho e colunas `sku;descricao;ncm;cest;origem;unidade;gtin;producao_propria` (aceita `;` ou `,`; as colunas `sku` e `ncm` são obrigatórias):

```bash
curl -s -X POST "$API/empresas/11222333000181/produtos/importacao" -H "Authorization: Bearer $CHAVE" -F "arquivo=@produtos.csv"
```

## Listar

`GET /empresas/{cnpj}/produtos?q=camiseta&per_page=50` devolve a lista paginada (ver [Paginação](02-autenticacao.md#paginacao)), ordenada por SKU. `q` procura no SKU, na descrição e no início do NCM.
