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

Uso interno da biblioteca: não faz parte da API pública.

A parte comum das raízes que a biblioteca monta e assina (`Nfse.DPS`, `Nfse.PedidoEvento`,
`Nfse.NFSe`): os campos que a biblioteca calcula e que o chamador não pode preencher, como o
`Id`; o `tp_amb`, que é sempre o do cliente; os valores provisórios que deixam o schema validar
antes de o valor calculado existir; a junção dos erros do chamador com os do schema; e a raiz
escrita em volta dos bytes assinados.

# `detail`

```elixir
@type detail() :: %{path: String.t(), error: atom()}
```

# `put_computed`

```elixir
@type put_computed() :: (struct() -&gt; {:ok, struct()} | {:error, [detail()]})
```

# `build_inf`

```elixir
@spec build_inf(module(), map(), Nfse.Client.t(), map(), put_computed()) ::
  {:ok, struct()} | {:error, Nfse.Error.t()}
```

Converte e valida `attrs` como o tipo `module` (o `TCInf...` da raiz): `prepare/4` seguido de
`validate/4`.

# `prepare`

```elixir
@spec prepare(module(), map(), Nfse.Client.t(), map()) :: {map(), [detail()]}
```

Junta a `attrs` os campos `computed`, que a biblioteca calcula, e o `tp_amb` do cliente, quando o
tipo `module` tem `tpAmb`. Devolve os attrs e os erros que só o chamador pode cometer: um campo de
`computed` preenchido é `:unknown_field`, e um `tp_amb` diferente do ambiente do cliente é
`:environment`.

O valor de um campo de `computed` é o definitivo ou um provisório, válido no padrão do schema,
que `validate/4` troca pelo calculado.

# `signed_xml`

```elixir
@spec signed_xml(struct(), String.t(), String.t(), Nfse.Certificate.t()) :: binary()
```

Escreve o `inf` validado como o elemento `inf_tag`, assina esses bytes com o `certificate` e
devolve a raiz `root_tag`, com o namespace da NFS-e e a versão `"1.01"`, em volta deles e da
assinatura.

# `to_attrs`

```elixir
@spec to_attrs(struct() | map()) :: map()
```

Os campos de um struct de raiz como mapa; um mapa passa como veio.

# `validate`

```elixir
@spec validate(module(), map(), [detail()], put_computed()) ::
  {:ok, struct()} | {:error, Nfse.Error.t()}
```

Converte e valida `attrs` como o tipo `module` e entrega o struct validado a `put_computed`, que
troca os valores provisórios pelos calculados e devolve `{:ok, struct}` ou `{:error, details}`.

A validação do tipo exige o `Id`, e o `Id` só sai dos campos já convertidos e validados (`n_dps:
42` vira `"42"`). Os `caller_errors`, os do schema e os de `put_computed` voltam juntos, antes de
qualquer assinatura.

# `version`

```elixir
@spec version() :: String.t()
```

A versão do leiaute que a biblioteca escreve.

---

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