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

# Importar e exportar

> Crie muitos insumos de uma vez a partir de um arquivo CSV, acompanhe a importação, corrija as linhas rejeitadas e exporte o seu catálogo.

Uma importação CSV cria insumos novos em lote. Ela nunca atualiza nem exclui insumos existentes. Uma exportação CSV baixa o catálogo inteiro em um arquivo, com custos apenas para quem pode vê-los.

## Quem pode fazer

| Ação | Quem |
| - | - |
| Importar um arquivo CSV | Pessoas com a função **Proprietário** ou **Administrador**. O servidor confere a própria função: um Membro que recebeu `catalog.manage` vê **Importar CSV**, mas o envio é recusado. Enquanto a importação roda, cada linha também é validada contra o `catalog.manage` de quem enviou o arquivo. |
| Abrir a página de status de uma importação | Pessoas da mesma clínica odontológica que tenham o link. |
| Exportar o catálogo | Pessoas com a função **Proprietário** ou **Administrador**. O botão **Exportar CSV** aparece para quem tem `catalog.manage`; um Membro com essa permissão é recusado da mesma forma. |
| Receber as colunas de custo em uma exportação | Quem exporta e também tem `catalog.cost.read`. |

A importação e a exportação são marcadas como ações sensíveis. Na versão atual o segundo fator (MFA) é opcional e não as bloqueia; se o console algum dia mostrar **Verifique sua identidade para continuar.**, confirme com o seu aplicativo autenticador e tente de novo. Veja [Segurança da conta](/docs/pt/account/security) e [Funções e permissões](/docs/pt/account/roles-and-permissions).

## Onde

| Tela | Caminho | Como chegar |
| - | - | - |
| **Importar CSV** | `/catalog/imports/new` | **Catálogo** e depois **Importar CSV**. |
| **Status da importação** | `/catalog/imports/:importId` | Abre sozinha depois de um envio. |
| Exportação | `/catalog` | **Catálogo** e depois **Exportar CSV**. |

<Note>
  Não existe uma lista de importações anteriores. Guarde o endereço da página **Status da importação** se quiser consultá-la depois.
</Note>

## Prepare o arquivo

A tela **Importar CSV** (**Adicione insumos de um arquivo CSV. Os insumos existentes não são atualizados.**) inclui um guia, **Prepare seu arquivo**, com:

* **Colunas obrigatórias** e **Colunas opcionais**.
* **Unidades aceitas** e **Criticidades aceitas**, com os códigos.
* **Baixar modelo de colunas**: um arquivo chamado `muveya-catalog-template.csv` só com a linha de cabeçalho.
* **IDs de categorias para seu CSV**: cada **Nome da categoria** ao lado do seu `categoryId`, com **Copiar ID da categoria**.

### Formato do arquivo

* CSV simples com vírgula como separador. Campos que contêm vírgulas, aspas duplas ou quebras de linha ficam entre aspas duplas, e uma aspa dupla dentro deles é escrita duas vezes (`""`).
* Codificado em UTF-8, com ou sem marca de ordem de bytes. Em uma planilha, salve como "CSV UTF-8".
* O primeiro registro é o cabeçalho. Os nomes das colunas são os nomes em inglês abaixo, escritos exatamente (maiúsculas contam), em qualquer ordem.
* Colunas que o muveya não conhece são ignoradas. Se uma coluna aparece duas vezes, vale a primeira, exceto `unitOfMeasure`, `cost`, `currency` e as colunas de metadados de custo: uma duplicata de qualquer uma delas recusa o arquivo inteiro.
* Linhas vazias são ignoradas. Os espaços em volta de cada valor são removidos.

<Warning>
  Planilhas configuradas em português ou espanhol costumam salvar CSV com ponto e vírgula. O muveya lê esse arquivo como uma única coluna, e a importação falha com **O arquivo não contém as colunas CSV obrigatórias.** Salve com vírgulas.
</Warning>

### Colunas

| Coluna | Obrigatória | Formato |
| - | - | - |
| `sku` | Sim | De 1 a 64 caracteres: letras, dígitos, `.`, `_`, `/`, `-`. Não pode existir ainda na sua clínica odontológica. |
| `name` | Sim | Até 200 caracteres. |
| `categoryId` | Sim | O identificador de uma categoria da sua clínica odontológica, copiado do guia. |
| `unitOfMeasure` | Sim | `unit`, `box`, `pack`, `bottle`, `ampoule`, `milliliter`, `liter`, `gram`, `kilogram`, `pair` ou `kit`. |
| `criticality` | Sim | `low`, `medium` ou `high`. |
| `description` | Não | Até 2.000 caracteres. |
| `packaging` | Não | Até 200 caracteres. É o campo de texto livre **Apresentação**. |
| `tracksLot`, `tracksSerial`, `tracksExpiry`, `highValue` | Não | `true` ou `false`. O muveya também aceita `1`/`0` e `yes`/`no`, com qualquer combinação de maiúsculas. Vazio significa `false`. |
| `cost` | Não | Um número inteiro de unidades menores, por exemplo `1200` para USD 12,00 ou CLP 1200. Só dígitos. Exige `currency`. |
| `currency` | Não | Três letras maiúsculas, por exemplo `BRL`. Exige `cost`. |
| `status` | Ignorada | Todo insumo importado é criado como `draft`. |
| `costStatus`, `costUnitOfMeasure`, `costMeasurementVersion`, `costQuantityProtocol` | Não | Metadados de custo gravados por uma exportação. Se qualquer uma delas estiver presente, as seis colunas de custo (`cost`, `currency` e estas quatro) precisam estar. Veja [Reimportar um arquivo exportado](#reimportar-um-arquivo-exportado). |

Exemplo:

```csv theme={null}
sku,name,categoryId,unitOfMeasure,criticality,description,packaging,tracksLot,tracksSerial,tracksExpiry,highValue,cost,currency
GLV-NIT-M,Nitrile gloves size M,665f1a2b3c4d5e6f7a8b9c01,unit,high,"Powder-free, blue",Box of 100,true,false,true,false,12,USD
ANS-LID-2,Lidocaine 2% cartridge,665f1a2b3c4d5e6f7a8b9c02,ampoule,high,,Box of 50,true,false,true,true,,
```

A segunda linha não tem custo: `cost` e `currency` estão vazios.

### Limites

| Limite | Valor | Quando é ultrapassado |
| - | - | - |
| Tamanho do arquivo | 5 MB (5.242.880 bytes), não vazio | O envio é recusado: **O arquivo deve ter no máximo 5 MB.** |
| Linhas de dados | 10.000 por arquivo, sem contar o cabeçalho | A importação inteira falha: **Use no máximo 10.000 linhas de dados por arquivo.** |
| Arquivos por importação | 1 | Divida catálogos grandes em vários arquivos. |

## Importar insumos

<Steps>
  <Step title="Prepare as categorias">
    Crie antes as categorias que faltam e copie os identificadores em **IDs de categorias para seu CSV**. Veja [Categorias](/docs/pt/catalog/categories).
  </Step>

  <Step title="Escolha o arquivo">
    Em **Importar CSV**, clique em **Arquivo CSV** e escolha o seu arquivo `.csv`.
  </Step>

  <Step title="Envie">
    Clique em **Importar insumos**. Quando o arquivo é aceito, o console abre **Status da importação**.
  </Step>

  <Step title="Acompanhe o andamento">
    A página se atualiza sozinha enquanto a importação aguarda processamento ou está em andamento. **Atualizar status** consulta de novo quando você quiser.
  </Step>

  <Step title="Revise o resultado">
    Leia os totais e as linhas rejeitadas. Corrija essas linhas em um arquivo novo e clique em **Importar outro arquivo**.
  </Step>

  <Step title="Ative os novos insumos">
    Os insumos importados ficam em rascunho. Abra cada um e ative-o quando estiver pronto para ser pedido. Não existe ativação em lote. Veja [Insumos do catálogo](/docs/pt/catalog/items).
  </Step>
</Steps>

## Status da importação

| Status | Título na página | Significado |
| - | - | - |
| `pending` | **Importação recebida** | O arquivo está salvo e aguarda processamento. |
| `processing` | **Importando insumos** | As linhas estão sendo criadas uma a uma, na ordem do arquivo. |
| `completed` | **Importação concluída** | Todas as linhas foram tentadas. Algumas podem ter sido rejeitadas. |
| `failed` | **Não foi possível concluir a importação** | O arquivo não pôde ser processado como um todo. Uma mensagem explica o motivo. |

```mermaid theme={null}
stateDiagram-v2
  [*] --> pending: Arquivo aceito
  pending --> processing: Processamento começa
  processing --> completed: Todas as linhas tentadas
  pending --> failed: Não pôde começar
  processing --> failed: Arquivo recusado ou interrompido
  failed --> processing: Nova tentativa automática após uma interrupção
```

Ao terminar, a página mostra **Linhas de dados**, **Criados** e **Rejeitados**. Se alguma linha foi rejeitada, ela acrescenta **Algumas linhas foram rejeitadas. Revise os motivos antes de enviar um arquivo corrigido.** e uma tabela com **Linha de dados** e **Motivo**.

Cada linha é independente: uma linha rejeitada nunca interrompe as outras, e as linhas criadas antes de uma rejeição continuam criadas.

### Números de linha

**São contados registros de dados, sem o cabeçalho; um registro CSV pode ocupar várias linhas de texto.** A linha de dados 1 é o primeiro registro depois do cabeçalho. Linhas vazias não contam, e um valor entre aspas com quebras de linha conta como uma única linha, então o número da linha de dados pode ser diferente do número de linha que o seu editor mostra.

## Falhas do arquivo inteiro

| Mensagem | Causa | O que fazer |
| - | - | - |
| **O arquivo não contém as colunas CSV obrigatórias.** | Falta uma coluna obrigatória ou ela está escrita errado, o separador não é vírgula, ficou uma aspa aberta, uma coluna de custo ou de unidade está duplicada, ou só algumas das seis colunas de custo estão presentes. | Corrija o cabeçalho ou as aspas e envie de novo. |
| **Use no máximo 10.000 linhas de dados por arquivo.** | Linhas demais. | Divida o arquivo. |
| **O arquivo enviado não está mais disponível. Envie-o novamente.** | O arquivo salvo não pôde ser lido de novo. | Envie o arquivo outra vez. |
| **O processamento foi interrompido. A recuperação automática tentará retomar o trabalho pendente.** | Uma falha temporária parou a importação. | Aguarde. A página continua consultando, e as linhas já criadas não são criadas duas vezes. |
| **Esta importação interrompida é anterior ao registro de progresso. Revise o catálogo existente antes de enviar um arquivo corrigido.** | Uma importação antiga foi interrompida antes de o muveya registrar o andamento por linha. | Procure no catálogo os SKUs do arquivo e envie só os que faltam. |

## Linhas rejeitadas

| Motivo exibido | Código | Causas comuns | Solução |
| - | - | - | - |
| **Falta um campo obrigatório.** | `catalog.import_row_incomplete` | `sku`, `name`, `categoryId`, `unitOfMeasure` ou `criticality` está vazio. | Preencha a célula. |
| **Falta um campo obrigatório.** | `catalog.cost_incomplete` | `cost` sem `currency`, ou `currency` sem `cost`. | Informe os dois ou nenhum. |
| **Revise os campos desta linha.** | `catalog.import_row_invalid` | Unidade ou criticidade desconhecida, um valor de rastreabilidade que não é `true` nem `false`, um `cost` que não é número, metadados de custo inconsistentes. | Use os valores permitidos. |
| **Revise os campos desta linha.** | `common.invalid_request` | SKU com espaços ou outros caracteres, um texto longo demais, um `categoryId` malformado, um `cost` com decimais ou negativo, uma `currency` que não são três letras maiúsculas. | Confira os formatos das colunas acima. |
| **Este SKU já existe.** | `catalog.sku_taken` | Já existe um insumo com esse SKU, inclusive um criado por uma linha anterior do mesmo arquivo. | Remova a linha ou use outro SKU. |
| **A categoria não existe nesta clínica.** | `catalog.category_not_found` | O `categoryId` tem formato válido, mas não é uma categoria desta clínica odontológica. | Copie o identificador em **IDs de categorias para seu CSV**. |
| **O custo registrado precisa de revisão. Confirme a unidade e o valor antes de importar esta linha.** | `catalog.cost_unverified` | A linha vem de uma exportação e o `costStatus` dela é `review_required` ou `invalid`. | Defina um custo confirmado ou esvazie as colunas de custo. |
| **A pessoa que enviou o arquivo não tem mais permissão.** | `tenants.insufficient_role` | Quem enviou o arquivo perdeu `catalog.manage` enquanto a importação rodava. | Peça a alguém com a função adequada que envie as linhas restantes. |
| **Não foi possível importar esta linha.** | Qualquer outro | Uma recusa inesperada. | Revise a linha; se continuar falhando, escreva para [team@muveya.com](mailto:team@muveya.com). |

Para corrigir linhas rejeitadas, monte um arquivo novo *só* com essas linhas, já corrigidas. Deixe de fora as linhas que foram criadas: agora elas seriam rejeitadas com **Este SKU já existe.**

## Importações nunca atualizam insumos

* Uma importação só cria insumos. Uma linha cujo SKU já existe é rejeitada, sejam quais forem os outros valores. Para mudar insumos existentes, edite-os no console.
* Dentro de um arquivo, a primeira linha com um SKU é criada e as seguintes com o mesmo SKU são rejeitadas.
* Enviar o mesmo arquivo duas vezes não cria nada na segunda vez: todas as linhas são rejeitadas por SKU existente.
* Se o processamento for interrompido e retomado, o muveya lembra quais linhas já criou e não as cria de novo.
* O custo de uma linha passa a ser o custo vigente do insumo, confirmado para a unidade de medida importada. Veja [Custos](/docs/pt/catalog/costs).

## Exportar o catálogo

<Steps>
  <Step title="Inicie a exportação">
    Em **Catálogo**, clique em **Exportar CSV**. O arquivo é gerado na hora.
  </Step>

  <Step title="Baixe">
    Clique em **Baixar CSV**. Abaixo do link, **O link expira:** mostra a data e a hora.
  </Step>
</Steps>

O link vale por 5 minutos. Depois disso, o console mostra **Este link expirou. Gere uma nova exportação.**; clique de novo em **Exportar CSV**. Se o console não conseguir verificar o link, mostra **Não foi possível verificar o link de download. Gere uma nova exportação.**

### Conteúdo da exportação

O arquivo se chama `catalog.csv` e contém todos os insumos da clínica odontológica, em todos os status, do mais antigo ao mais recente.

| Colunas | Incluídas |
| - | - |
| `sku`, `name`, `description`, `categoryId`, `unitOfMeasure`, `packaging`, `criticality`, `tracksLot`, `tracksSerial`, `tracksExpiry`, `highValue`, `status` | Sempre. |
| `cost`, `currency`, `costStatus`, `costUnitOfMeasure`, `costMeasurementVersion`, `costQuantityProtocol` | Só se você tem `catalog.cost.read`. Sem essa permissão, essas colunas não existem no arquivo. |

* Valores opcionais vazios são células vazias; as colunas de rastreabilidade valem `true` ou `false`; `cost` e `currency` ficam vazios quando o custo é `unset`.
* O arquivo está em UTF-8 com marca de ordem de bytes, separado por vírgulas e com quebras de linha do Windows, para que as planilhas abram corretamente os nomes com acentos.
* Um valor que começa com `=`, `+`, `-` ou `@` é gravado com um apóstrofo (`'`) na frente, para que a planilha não o execute como fórmula.
* As categorias aparecem como `categoryId`, não pelo nome. Apresentações, códigos de embalagem e estoque não são exportados.

### Reimportar um arquivo exportado

Uma exportação tem os mesmos nomes de coluna da importação, então você pode usá-la como ponto de partida, por exemplo para carregar o mesmo catálogo em outra clínica odontológica. Antes de enviar:

* Troque cada `categoryId` pelos identificadores da clínica odontológica de destino.
* Remova o apóstrofo que a exportação colocou na frente dos valores que começam com `=`, `+`, `-` ou `@`.
* A coluna `status` é ignorada: todo insumo é criado como rascunho.
* Se o arquivo tiver as colunas de custo, o `costStatus` de cada linha decide o que acontece:
  * `unset`: as demais células de custo precisam estar vazias.
  * `verified`: `costUnitOfMeasure` precisa ser igual a `unitOfMeasure`, `costMeasurementVersion` um número inteiro a partir de 1, `costQuantityProtocol` precisa ser `base_number_v1`, `cost` um número inteiro e `currency` três letras maiúsculas. Caso contrário, a linha é rejeitada com **Revise os campos desta linha.**
  * `review_required` ou `invalid`: a linha é rejeitada com **O custo registrado precisa de revisão. Confirme a unidade e o valor antes de importar esta linha.**
  * Vazio ou qualquer outro valor: a linha é rejeitada com **Revise os campos desta linha.**
* Reimportar na mesma clínica odontológica não cria nada, porque todos os SKUs já existem.

## O que o sistema registra

| Evento | Entrada de auditoria |
| - | - |
| Um envio aceito | `catalog.import`, com o nome do arquivo, o tamanho e quem o enviou; a entrada é concluída quando a importação termina ou falha. |
| Um envio recusado | `catalog.import.denied`, com o nome do arquivo. |
| Uma exportação | `catalog.export`, com a quantidade de insumos e se os custos foram incluídos. Nunca os valores de custo. |
| Uma exportação recusada | `catalog.export.denied`. |

A importação também guarda, para cada linha de dados, se ela foi criada e o motivo quando não foi. Esse resumo nunca guarda valores de custo. A versão atual não tem uma tela para consultar a auditoria.

## O que pode dar errado ao enviar ou exportar

| Mensagem | Código | O que fazer |
| - | - | - |
| **Escolha um arquivo CSV.** | `catalog.import_file_missing`, `catalog.import_empty` | Escolha um arquivo que não esteja vazio. |
| **O arquivo deve ter no máximo 5 MB.** | `catalog.import_too_large` | Divida o arquivo. |
| **Sua conta não tem permissão para esta ação.** | `tenants.insufficient_role` | Peça a um Proprietário ou Administrador que importe ou exporte. |
| **Este registro não está disponível na conta de clínica odontológica ativa.** | `catalog.import_not_found` | A importação pertence a outra clínica odontológica ou o link está errado. |
| **Verifique sua identidade para continuar.** | `auth.mfa_required` | Confirme com o seu aplicativo autenticador e tente de novo. |

A API pública não importa nem exporta o catálogo. Para lê-lo a partir de outro sistema, use `GET /v1/catalog/items`. Veja [API para desenvolvedores](/docs/pt/api-reference/introduction).

## Páginas relacionadas

<CardGroup cols={2}>
  <Card title="Insumos do catálogo" icon="box" href="/docs/pt/catalog/items">
    Regras dos campos e ativação.
  </Card>

  <Card title="Categorias" icon="tags" href="/docs/pt/catalog/categories">
    Crie categorias e encontre os identificadores.
  </Card>

  <Card title="Custos" icon="coins" href="/docs/pt/catalog/costs">
    Unidades menores e estados do custo.
  </Card>

  <Card title="Funções e permissões" icon="user-shield" href="/docs/pt/account/roles-and-permissions">
    Funções que podem importar e exportar.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.