# `Nfse.Sefin`
[🔗](https://github.com/ideia4it/nfse/blob/v0.1.0/lib/nfse/sefin.ex#L1)

Emissão e consultas na Sefin Nacional. As funções são expostas por `Nfse`.

A emissão é síncrona: `POST /nfse` recebe a DPS assinada e responde, na mesma chamada, com a
NFS-e. Por isso uma emissão que não obteve resposta (`:timeout`, `:transport` ou `:server`) tem
resultado incerto, e a biblioteca a envia uma única vez. O `Nfse.Error` volta com o `dps_id`, que
se confere com `dps_issued?/2` e `fetch_access_key/2` antes de qualquer reenvio. Todo erro de
`issue/2` posterior à montagem da DPS carrega o `dps_id`.

Uma resposta 2xx que não se consegue ler, na emissão, na consulta ou num evento, volta como
`:unexpected` com o `status` da resposta, nunca como `:validation`: o documento existe na Sefin.
`details` é sempre `%{access_key: ..., xml: ..., reason: ...}`, com `nil` no que não se chegou a
ler e, em `reason`, o `Nfse.Error` da etapa que falhou. Numa escrita, esse erro é incerto como
um `:timeout`, e o `dps_id` também vem nele.

A documentação da Sefin descreve a resposta de sucesso em camelCase, mas os erros chegam em
PascalCase; os campos de sucesso são lidos nas duas grafias.

## Decisão judicial

`issue_by_court_order/2` envia a NFS-e inteira, montada e assinada por `Nfse.NFSe`, a
`POST /decisao-judicial/nfse`, que responde como a emissão normal. A escrita também sai uma única
vez, e o erro carrega o `dps_id` da DPS embutida.

## Eventos

`register_event/2` envia o pedido assinado a `POST /nfse/{chave}/eventos` e `fetch_event/4` lê um
evento em `GET /nfse/{chave}/eventos/{tipo}/{sequência}`. Como na emissão, a escrita sai uma única
vez: um `:timeout`, um `:server` ou um 2xx ilegível deixa o resultado incerto, e o evento se
confere com `fetch_event/4` antes de qualquer reenvio. A recusa de um evento chega com um único
objeto `erro`, que o cliente já lê.

## O que não está confirmado

Itens da Sefin ainda sem prova contra o ambiente de produção restrita:

  * o caminho da Sefin em produção restrita: `/API/SefinNacional`, como no portal gov.br, ou
    `/SefinNacional`
  * a assinatura da DPS em RSA-SHA1 ou RSA-SHA256
  * se o ME/EPP do Simples Nacional informa `pAliq`
  * a série com `^` ou `$`, que o padrão do schema permite
  * emoji no `xNome`, que o XSD não restringe e a biblioteca aceita; se a Sefin o recusar, a
    recusa chega como `:rejected`
  * campo de texto só com espaços em branco, que a biblioteca nunca apara e envia como está
  * a recusa de uma DPS repetida pelo `Id`: se a Sefin a aceitar, reenviar depois de uma
    conferência negativa emite a nota duas vezes
  * a resposta de `GET /nfse/{chave}/eventos/{tipo}/{sequência}`, documentada com o mesmo campo
    `eventoXmlGZipB64` da resposta do registro, ainda não vista de verdade

# `decode_evento`

```elixir
@spec decode_evento(binary()) :: {:ok, struct()} | {:error, Nfse.Error.t()}
```

Lê o XML de um evento na versão que o atributo `versao` da raiz indica.

# `decode_nfse`

```elixir
@spec decode_nfse(binary()) :: {:ok, struct()} | {:error, Nfse.Error.t()}
```

Lê o XML de uma NFS-e na versão que o atributo `versao` da raiz indica.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
