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

Cliente Elixir para a NFS-e Nacional.

# `benefit`

```elixir
@spec benefit(Nfse.Client.t(), String.t(), String.t() | integer(), Date.t()) ::
  {:ok, map()} | {:error, Nfse.Error.t()}
```

Lê um benefício municipal pelo número, na competência.

# `cancel`

```elixir
@spec cancel(Nfse.Client.t(), String.t(), keyword()) ::
  {:ok, Nfse.Event.t()} | {:error, Nfse.Error.t()}
```

Cancela uma NFS-e pelo evento `101101`.

Opções: `:c_motivo` (`1` erro na emissão, `2` serviço não prestado, `9` outros) e `:x_motivo`
(de 15 a 255 caracteres), obrigatórias, e `:ver_aplic`, que por padrão é `"nfse-"` seguido da
versão da biblioteca. O autor é o dono do certificado do cliente.

# `distribution`

```elixir
@spec distribution(Nfse.Client.t(), non_neg_integer(), keyword()) ::
  {:ok, Nfse.Distribution.t()} | {:error, Nfse.Error.t()}
```

Lê um lote da distribuição do ADN: os documentos fiscais em que o CNPJ do certificado aparece,
depois do `nsu` informado, em até 50 por chamada.

Opção: `:cnpj_consulta`, para consultar outro CNPJ da mesma raiz. O `next_nsu` do resultado é o
ponto de partida da próxima chamada. O fim da fila é `{:ok, %Nfse.Distribution{status:
:no_documents}}`, nunca erro. Um lote com documentos que não avança o NSU volta como
`{:error, %Nfse.Error{kind: :unexpected, details: {:stalled_nsu, nsu}}}`. Veja `Nfse.Adn`.

# `dps_issued?`

```elixir
@spec dps_issued?(Nfse.Client.t(), String.t()) ::
  {:ok, boolean()} | {:error, Nfse.Error.t()}
```

Confere se uma DPS virou NFS-e: `{:ok, true}` quando a Sefin a conhece e `{:ok, false}` quando
não.

# `events`

```elixir
@spec events(Nfse.Client.t(), String.t()) ::
  {:ok, [Nfse.DistributedDocument.t()]} | {:error, Nfse.Error.t()}
```

Lista os documentos de evento de uma NFS-e (cancelamentos, manifestações) pelo ADN.

# `fetch`

```elixir
@spec fetch(Nfse.Client.t(), String.t()) ::
  {:ok, Nfse.Document.t()} | {:error, Nfse.Error.t()}
```

Consulta uma NFS-e na Sefin pela chave de acesso de 50 dígitos.

# `fetch_access_key`

```elixir
@spec fetch_access_key(Nfse.Client.t(), String.t()) ::
  {:ok, String.t()} | {:error, Nfse.Error.t()}
```

Busca a chave de acesso da NFS-e emitida a partir do `Id` da DPS.

# `fetch_event`

```elixir
@spec fetch_event(Nfse.Client.t(), String.t(), String.t(), pos_integer()) ::
  {:ok, Nfse.Event.t()} | {:error, Nfse.Error.t()}
```

Consulta um evento da NFS-e pelo tipo (como `"101101"`) e pelo número de sequência.

Antes da rede, confere a chave de acesso (50 dígitos), o tipo (6 dígitos) e a sequência (inteiro
positivo), e devolve os erros juntos como `%Nfse.Error{kind: :validation}`, nos caminhos
`access_key`, `tipo_evento` e `n_seq_evento`.

# `issue`

```elixir
@spec issue(Nfse.Client.t(), Nfse.DPS.t() | map()) ::
  {:ok, Nfse.Issued.t()} | {:error, Nfse.Error.t()}
```

Emite a NFS-e a partir de uma DPS, de forma síncrona.

Monta, valida e assina a DPS (`Nfse.DPS.build/2`) e a envia à Sefin uma única vez. Se a Sefin não
responder (`:timeout`, `:transport` ou `:server`) ou responder 2xx com algo que não se lê
(`:unexpected` com `status`), o resultado é incerto: o `Nfse.Error` traz o `dps_id` para conferir
com `dps_issued?/2` e `fetch_access_key/2` antes de reenviar.

# `issue_by_court_order`

```elixir
@spec issue_by_court_order(Nfse.Client.t(), Nfse.NFSe.t() | map()) ::
  {:ok, Nfse.Issued.t()} | {:error, Nfse.Error.t()}
```

Emite a NFS-e por decisão administrativa ou judicial, de forma síncrona.

Monta, valida e assina a NFS-e inteira (`Nfse.NFSe.build/2`) e a envia à Sefin uma única vez. O
município precisa ter cadastrado a decisão e autorizado o contribuinte antes. Se a Sefin não
responder, o resultado é incerto, como em `issue/2`.

# `municipal_agreement`

```elixir
@spec municipal_agreement(Nfse.Client.t(), String.t()) ::
  {:ok, map()} | {:error, Nfse.Error.t()}
```

Lê os parâmetros do convênio do município (código IBGE de sete dígitos) com o ADN.

# `rate`

```elixir
@spec rate(Nfse.Client.t(), String.t(), String.t(), Date.t()) ::
  {:ok, map()} | {:error, Nfse.Error.t()}
```

Lê a alíquota de ISS de um serviço no município, na competência (um `Date`). O código do
serviço aceita os nove dígitos com ou sem pontos. Veja `Nfse.Parametros`.

# `rate_history`

```elixir
@spec rate_history(Nfse.Client.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, Nfse.Error.t()}
```

Lê o histórico de alíquotas de ISS de um serviço no município.

# `register_event`

```elixir
@spec register_event(Nfse.Client.t(), Nfse.PedidoEvento.t() | map()) ::
  {:ok, Nfse.Event.t()} | {:error, Nfse.Error.t()}
```

Registra um evento da NFS-e, como a solicitação de análise fiscal ou a manifestação do tomador.

Monta, valida e assina o pedido (`Nfse.PedidoEvento.build/2`) e o envia à Sefin uma única vez.
Se a Sefin não responder (`:timeout`, `:transport` ou `:server`) ou responder 2xx com algo que
não se lê (`:unexpected` com `status`), o resultado é incerto: confira com `fetch_event/4` antes
de reenviar.

# `special_regimes`

```elixir
@spec special_regimes(Nfse.Client.t(), String.t(), String.t(), Date.t()) ::
  {:ok, map()} | {:error, Nfse.Error.t()}
```

Lê os regimes especiais de um serviço no município, na competência.

# `stream_distribution`

```elixir
@spec stream_distribution(Nfse.Client.t(), non_neg_integer(), keyword()) ::
  Enumerable.t(Nfse.DistributedDocument.t())
```

Percorre a distribuição do ADN, lote a lote, a partir do `nsu`, e entrega os documentos um a um
até o fim da fila. Aceita as mesmas opções de `distribution/3`.

Diferente das demais funções, levanta `Nfse.Error` quando um lote falha.

# `withholdings`

```elixir
@spec withholdings(Nfse.Client.t(), String.t(), Date.t()) ::
  {:ok, map()} | {:error, Nfse.Error.t()}
```

Lê os parâmetros de retenção do município na competência.

---

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