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

# Referência de templates

> Consulte cada tag, filtro e operador disponíveis no Reporter — loops, condicionais, placeholders e helpers de formatação integrados.

Esta página é uma referência completa de todas as tags, filtros e operadores de templates disponíveis no Reporter. Para uma introdução aos templates e placeholders, consulte [O que é o Reporter](/pt/reporter/what-is-reporter).

## Construindo templates

***

### Blocos comuns

* **Loop**

```
{% for <item> in <list> %}
  ...
{% endfor %}
```

* **Loop com schema explícito**

```
{% for order in external_db:sales.orders %}
  {{ order.id }} - {{ order.total }}
{% endfor %}
```

* **Condição simples**

```
{% if value_a == value_b %}
  ...
{% endif %}
```

* **Escopo temporário**

```
{% with <object> as <alias> %}
  ...
{% endwith %}
```

* **Formatação de valores**

```
{{ field_name | floatformat:2 }}   --> renderiza 123.45
```

### Blocos condicionais

| Bloco          | Descrição                                                  | Exemplo                                                |
| -------------- | ---------------------------------------------------------- | ------------------------------------------------------ |
| If             | Executa o bloco se a condição for verdadeira               | `{% if condition %}...{% endif %}`                     |
| If-else        | Executa um bloco se verdadeiro, outro se falso             | `{% if condition %}...{% else %}...{% endif %}`        |
| If-else-if     | Permite múltiplas verificações                             | `{% if a %}...{% elif b %}...{% else %}...{% endif %}` |
| Igual          | Verifica se dois valores são iguais                        | `{% if a == b %}`                                      |
| Diferente      | Verifica se dois valores são diferentes                    | `{% if a != b %}`                                      |
| Maior que      | Verifica se a é maior que b                                | `{% if a > b %}`                                       |
| Menor que      | Verifica se a é menor que b                                | `{% if a < b %}`                                       |
| Maior ou igual | Verifica se a é maior ou igual a b                         | `{% if a >= b %}`                                      |
| Menor ou igual | Verifica se a é menor ou igual a b                         | `{% if a <= b %}`                                      |
| And            | Retorna verdadeiro se ambas as condições forem verdadeiras | `{% if a and b %}`                                     |
| Or             | Retorna verdadeiro se pelo menos uma for verdadeira        | `{% if a or b %}`                                      |
| Not            | Inverte o resultado booleano                               | `{% if not a %}`                                       |

## Referência de tags

***

### Tags de agregação

**sum\_by** -- Soma valores numéricos de um campo em todos os itens de uma coleção.

```
{% sum_by <collection> by <field> %}
{% sum_by <collection> by <field> if <condition> %}
```

**Exemplo:**

```xml theme={null}
<Sum>
  {% sum_by transaction.operation by "amount" if accountAlias != "@external/BRL" %}
</Sum>
```

**count\_by** -- Conta o número de itens em uma coleção.

```
{% count_by <collection> %}
{% count_by <collection> if <condition> %}
```

**Exemplo:**

```xml theme={null}
<Count>
  {% count_by transaction.operation if accountAlias != "@external/BRL" %}
</Count>
```

**avg\_by** -- Calcula a média dos valores numéricos de um campo.

```
{% avg_by <collection> by <field> %}
{% avg_by <collection> by <field> if <condition> %}
```

**min\_by** -- Encontra o valor numérico mínimo de um campo.

```
{% min_by <collection> by <field> %}
{% min_by <collection> by <field> if <condition> %}
```

**max\_by** -- Encontra o valor numérico máximo de um campo.

```
{% max_by <collection> by <field> %}
{% max_by <collection> by <field> if <condition> %}
```

<Note>
  Todas as tags de agregação utilizam precisão decimal para evitar erros de arredondamento de ponto flutuante. Campos ausentes ou não numéricos são ignorados. Retorna `0` se nenhum item corresponder.
</Note>

### Tag de data e hora

**date\_time** -- Gera a data e hora atuais formatadas de acordo com a string de formato fornecida. O horário é gerado em UTC.

```
{% date_time "<format>" %}
```

**Códigos de formato:**

| Código | Significado              | Exemplo |
| ------ | ------------------------ | ------- |
| `YYYY` | Ano com 4 dígitos        | 2025    |
| `MM`   | Mês com 2 dígitos        | 01-12   |
| `dd`   | Dia com 2 dígitos        | 01-31   |
| `HH`   | Hora com 2 dígitos (24h) | 00-23   |
| `mm`   | Minuto com 2 dígitos     | 00-59   |
| `ss`   | Segundo com 2 dígitos    | 00-59   |

**Exemplos:**

```
{% date_time "YYYY-MM-dd" %}           --> 2025-02-06
{% date_time "dd/MM/YYYY HH:mm:ss" %} --> 06/02/2025 14:30:45
```

### Tag aritmética

**calc** -- Avalia expressões matemáticas com suporte a variáveis do contexto do template.

```
{% calc <expression> %}
```

**Operadores suportados:**

| Operador | Descrição              | Precedência                       |
| -------- | ---------------------- | --------------------------------- |
| `**`     | Exponenciação          | Mais alta (direita para esquerda) |
| `*` `/`  | Multiplicação, divisão | Média                             |
| `+` `-`  | Adição, subtração      | Mais baixa                        |
| `( )`    | Parênteses             | Sobrescreve a precedência         |

**Exemplos:**

```
{% calc 100 + 50 %}                                --> 150
{% calc balance.available * 0.5 %}                 --> valor calculado
{% calc (balance.available + 1.2) * balance.on_hold - balance.available / 2 %}
```

<Note>
  Variáveis que não podem ser resolvidas assumem o valor padrão `0`. Divisão por zero produz um erro.
</Note>

### Tag de seleção agrupada

**last\_item\_by\_group** -- Agrupa itens por um campo e seleciona o item mais recente de cada grupo, ordenado por um campo de data (descendente). Opcionalmente, filtra os itens primeiro. Útil para relatórios regulatórios que exigem o registro mais recente por conta agrupado por categoria.

```
{% last_item_by_group <collection> group_by "<group_field>" order_by "<date_field>" [if <condition>] as <result_var> %}
```

O resultado é uma lista de itens -- o mais recente de cada grupo -- armazenada em uma variável que você pode iterar. Cada elemento é o registro original da coleção, então você acessa os campos dele:

```
{% last_item_by_group accounts group_by "cosif_code" order_by "created_at" as latest %}
{% for account in latest %}
  {{ account.cosif_code }}: {{ account.balance }}
{% endfor %}
```

<Note>
  `group_by` aceita uma lista de campos separados por vírgula para agrupamento composto. Tamanho máximo da coleção: 100.000 itens. Os resultados são ordenados pelo valor de `group_by` para uma saída determinística.
</Note>

### Tags de contador

**counter** -- Incrementa um contador nomeado em 1. Não produz saída. Os contadores têm escopo por renderização.

```
{% counter "<counter_name>" %}
```

**counter\_show** -- Exibe a soma de um ou mais contadores nomeados.

```
{% counter_show "<name1>" %}
{% counter_show "<name1>" "<name2>" "<name3>" %}
```

**Exemplo:**

```
{% for tx in ledger.transactions %}
  {% counter tx.type %}
{% endfor %}
Total créditos: {% counter_show "credit" %}
Total débitos: {% counter_show "debit" %}
Combinado: {% counter_show "credit" "debit" %}
```

## Referência de filtros

***

### percent\_of

Calcula a porcentagem de um valor em relação a um total. Retorna uma string formatada com 2 casas decimais.

```
{{ value | percent_of: total }}
```

Exemplo: se `category.amount = "6.00"` e `total.expenses = "20.00"`:

```
{{ category.amount | percent_of: total.expenses }}  --> 30.00%
```

### strip\_zeros

Remove zeros à direita de um valor numérico sem arredondamento.

```
{{ number | strip_zeros }}
```

**Exemplos:**

```
{{ "100.50000" | strip_zeros }}  --> 100.5
{{ "100.00" | strip_zeros }}     --> 100
{{ "99.990" | strip_zeros }}     --> 99.99
```

### slice

Extrai uma substring usando índices de início e fim (base 0).

```
{{ string | slice:"start:end" }}
```

**Exemplos:**

```
{{ "hello" | slice:"0:3" }}  --> hel
{{ "12345" | slice:"1:4" }}  --> 234
```

### replace

Substitui todas as ocorrências de uma string de busca por uma string de substituição. Formato: `"busca:substituição"`.

```
{{ string | replace:"search:replacement" }}
```

**Exemplos:**

```
{{ "01310-100" | replace:"-:" }}      --> 01310100   (remove hifens)
{{ "1234.56" | replace:".:," }}       --> 1234,56    (ponto para vírgula)
{{ "12.345.678/0001-99" | replace:".:" }}  --> 12345678/0001-99
```

### where

Filtra um array de objetos por igualdade de campo. Suporta campos aninhados via notação de ponto.

```
{{ array | where:"field:value" }}
```

**Exemplos:**

```
{{ holders | where:"state:SP" }}
{{ holders | where:"address.state:SP" }}
```

Uso dentro de loops:

```
{% for holder in holders|where:"state:SP" %}
  {{ holder.name }}
{% endfor %}
```

### sum (filtro)

Soma valores numéricos de um campo em todos os itens de um array. Utiliza precisão decimal.

```
{{ array | sum:"field" }}
```

**Exemplos:**

```
{{ operations | sum:"amount" }}
{{ items | sum:"price.value" }}
```

### count (filtro)

Conta elementos em um array onde um campo corresponde a um valor. Suporta campos aninhados.

```
{{ array | count:"field:value" }}
```

**Exemplos:**

```
{{ operations | count:"nat_oper:6" }}
{{ holders | count:"address.state:SP" }}
```

### contains

Verifica se um valor está parcialmente contido em outro. Útil quando os dados incluem prefixos ou sufixos dinâmicos.

```
{% if contains(source_field, target_field) %}
```

**Exemplo:**

* Origem: `0#@external/BRL`
* Destino: `@external/BRL`

Retorna `true` porque `@external/BRL` existe dentro do valor de origem.

## Resumo de operadores e filtros

***

| Nome                 | Tipo   | Descrição                                  |
| -------------------- | ------ | ------------------------------------------ |
| `sum_by`             | Tag    | Soma valores por campo com filtro opcional |
| `count_by`           | Tag    | Conta itens com filtro opcional            |
| `avg_by`             | Tag    | Calcula a média por campo                  |
| `min_by`             | Tag    | Encontra o valor mínimo                    |
| `max_by`             | Tag    | Encontra o valor máximo                    |
| `date_time`          | Tag    | Formata a data/hora atual                  |
| `calc`               | Tag    | Avalia expressões aritméticas              |
| `last_item_by_group` | Tag    | Item mais recente por grupo segundo a data |
| `counter`            | Tag    | Incrementa um contador nomeado             |
| `counter_show`       | Tag    | Exibe valor(es) do contador                |
| `percent_of`         | Filtro | Calcula porcentagem                        |
| `strip_zeros`        | Filtro | Remove zeros à direita                     |
| `slice`              | Filtro | Extrai substring                           |
| `replace`            | Filtro | Substituição de string                     |
| `where`              | Filtro | Filtra array por valor de campo            |
| `sum`                | Filtro | Soma valores de campo do array             |
| `count`              | Filtro | Conta itens correspondentes                |
| `contains`           | Função | Correspondência parcial de string          |
| `floatformat`        | Filtro | Formata casas decimais                     |

## Filtragem avançada

***

Ao gerar um relatório, você pode passar filtros no corpo da requisição para restringir os dados. Os filtros seguem uma estrutura de datasource > tabela > campo:

**Schema único (padrão):**

```json theme={null}
{
  "templateId": "00000000-0000-0000-0000-000000000000",
  "filters": {
    "midaz_onboarding": {
      "account": {
        "id": { "eq": ["123", "456"] },
        "createdAt": { "between": ["2023-01-01", "2023-01-31"] },
        "status": { "in": ["active", "pending"] }
      }
    }
  }
}
```

**Multi-schema (chave explícita schema.tabela):**

```json theme={null}
{
  "templateId": "00000000-0000-0000-0000-000000000000",
  "filters": {
    "external_db": {
      "sales.orders": {
        "total": { "gt": [100] },
        "created_at": { "gte": ["2025-01-01"] }
      },
      "finance.invoices": {
        "status": { "eq": ["paid"] }
      }
    }
  }
}
```

**Operadores suportados:**

| Operador  | Descrição                    | Exemplo                              |
| --------- | ---------------------------- | ------------------------------------ |
| `eq`      | Igual a                      | `{ "eq": ["active", "pending"] }`    |
| `gt`      | Maior que                    | `{ "gt": [100] }`                    |
| `gte`     | Maior ou igual a             | `{ "gte": ["2025-06-01"] }`          |
| `lt`      | Menor que                    | `{ "lt": [1000] }`                   |
| `lte`     | Menor ou igual a             | `{ "lte": ["2025-06-30"] }`          |
| `between` | Valor dentro de um intervalo | `{ "between": [100, 1000] }`         |
| `in`      | Valor está em uma lista      | `{ "in": ["active", "pending"] }`    |
| `nin`     | Valor não está em uma lista  | `{ "nin": ["deleted", "archived"] }` |
