> ## 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.

# Referencia de plantillas

> Consulta todas las etiquetas, filtros y operadores de plantilla disponibles en Reporter: bucles, condicionales, marcadores de posición y funciones auxiliares de formato integradas.

Esta página es una referencia completa de todas las etiquetas, filtros y operadores de plantilla disponibles en Reporter. Para una introducción a las plantillas y los marcadores de posición, consulta [¿Qué es Reporter?](/es/products/reporter/what-is-reporter).

## Construcción de plantillas

***

### Bloques comunes

* **Bucle**

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

* **Bucle con esquema explícito**

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

* **Condición simple**

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

* **Ámbito temporal**

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

* **Formato de valores**

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

### Bloques condicionales

| Bloque            | Descripción                                            | Ejemplo                                                |
| ----------------- | ------------------------------------------------------ | ------------------------------------------------------ |
| Si                | Ejecuta el bloque si la condición es verdadera         | `{% if condition %}...{% endif %}`                     |
| Si-si no          | Ejecuta un bloque si es verdadero y otro si es falso   | `{% if condition %}...{% else %}...{% endif %}`        |
| Si-si no-si       | Permite varias verificaciones                          | `{% if a %}...{% elif b %}...{% else %}...{% endif %}` |
| Igual             | Verifica si dos valores son iguales                    | `{% if a == b %}`                                      |
| Distinto          | Verifica si dos valores son diferentes                 | `{% if a != b %}`                                      |
| Mayor que         | Verifica si a es mayor que b                           | `{% if a > b %}`                                       |
| Menor que         | Verifica si a es menor que b                           | `{% if a < b %}`                                       |
| Mayor o igual que | Verifica si a es mayor o igual que b                   | `{% if a >= b %}`                                      |
| Menor o igual que | Verifica si a es menor o igual que b                   | `{% if a <= b %}`                                      |
| Y                 | Devuelve verdadero si ambas condiciones son verdaderas | `{% if a and b %}`                                     |
| O                 | Devuelve verdadero si al menos una es verdadera        | `{% if a or b %}`                                      |
| No                | Invierte el resultado booleano                         | `{% if not a %}`                                       |

## Referencia de etiquetas

***

### Etiquetas de agregación

**sum\_by** -- Suma los valores numéricos de un campo en todos los elementos de una colección.

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

**Ejemplo:**

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

**count\_by** -- Cuenta el número de elementos de una colección.

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

**Ejemplo:**

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

**avg\_by** -- Calcula el promedio de los valores numéricos de un campo.

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

**min\_by** -- Encuentra el valor numérico mínimo de un campo.

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

**max\_by** -- Encuentra el valor numérico máximo de un campo.

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

<Note>
  Todas las etiquetas de agregación usan precisión decimal para evitar errores de redondeo de punto flotante. Los campos faltantes o no numéricos se omiten. Devuelve `0` si no hay elementos que coincidan.
</Note>

### Etiqueta de fecha y hora

**date\_time** -- Muestra la fecha y hora actuales en la zona horaria local del runtime de Reporter, con el formato indicado en la cadena de formato proporcionada.

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

**Códigos de formato:**

| Código | Significado              | Ejemplo |
| ------ | ------------------------ | ------- |
| `YYYY` | Año de 4 dígitos         | 2025    |
| `MM`   | Mes de 2 dígitos         | 01-12   |
| `dd`   | Día de 2 dígitos         | 01-31   |
| `HH`   | Hora de 2 dígitos (24 h) | 00-23   |
| `mm`   | Minuto de 2 dígitos      | 00-59   |
| `ss`   | Segundo de 2 dígitos     | 00-59   |

**Ejemplos:**

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

### Etiqueta aritmética

**calc** -- Evalúa expresiones matemáticas y admite variables del contexto de la plantilla.

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

**Operadores admitidos:**

| Operador | Descripción              | Precedencia                       |
| -------- | ------------------------ | --------------------------------- |
| `**`     | Exponenciación           | Más alta (de derecha a izquierda) |
| `*` `/`  | Multiplicación, división | Media                             |
| `+` `-`  | Suma, resta              | Más baja                          |
| `( )`    | Paréntesis               | Anula la precedencia              |

**Ejemplos:**

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

<Note>
  Las variables que no se pueden resolver usan `0` de forma predeterminada. La división entre cero produce un error.
</Note>

### Etiqueta de selección agrupada

**last\_item\_by\_group** -- Agrupa los elementos por un campo y selecciona el más reciente de cada grupo, ordenado por un campo de fecha (descendente). Opcionalmente, filtra los elementos primero. Es útil para informes regulatorios que requieren el registro más reciente por cuenta, agrupado por categoría.

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

El resultado es una lista de elementos -- el más reciente de cada grupo -- almacenada en una variable que puedes recorrer. Cada elemento es el registro original de la colección, por lo que accedes a sus propios campos:

```
{% 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` acepta una lista de campos separados por comas para agrupamiento compuesto. Tamaño máximo de la colección: 100,000 elementos. Los resultados se ordenan por el valor de `group_by` para una salida determinista.
</Note>

### Etiquetas de contador

**counter** -- Incrementa en 1 un contador con nombre. No genera salida. Los contadores tienen ámbito por renderización.

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

**counter\_show** -- Muestra la suma de uno o más contadores con nombre.

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

**Ejemplo:**

```
{% for tx in ledger.transactions %}
  {% counter tx.type %}
{% endfor %}
Total credits: {% counter_show "credit" %}
Total debits: {% counter_show "debit" %}
Combined: {% counter_show "credit" "debit" %}
```

## Referencia de filtros

***

### percent\_of

Calcula el porcentaje de un valor con respecto a un total. Devuelve una cadena con formato de 2 decimales.

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

Ejemplo: si `category.amount = "6.00"` y `total.expenses = "20.00"`:

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

### strip\_zeros

Elimina los ceros finales de un valor numérico sin redondear.

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

**Ejemplos:**

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

### slice

Extrae una subcadena usando índices de inicio y fin (basados en 0).

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

**Ejemplos:**

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

### replace

Reemplaza todas las repeticiones de una cadena de búsqueda por una cadena de reemplazo. Formato: `"search:replacement"`.

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

**Ejemplos:**

```
{{ "01310-100" | replace:"-:" }}      --> 01310100   (removes hyphens)
{{ "1234.56" | replace:".:," }}       --> 1234,56    (dot to comma)
{{ "12.345.678/0001-99" | replace:".:" }}  --> 12345678/0001-99
```

### where

Filtra un array de objetos por igualdad de campo. Admite campos anidados mediante notación de puntos.

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

**Ejemplos:**

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

Se usa dentro de bucles:

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

### sum (filtro)

Suma los valores numéricos de un campo en todos los elementos de un array. Usa precisión decimal.

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

**Ejemplos:**

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

### count (filtro)

Cuenta los elementos de un array en los que un campo coincide con un valor. Admite campos anidados.

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

**Ejemplos:**

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

### contains

Verifica si un valor está parcialmente incluido en otro. Es útil cuando los datos incluyen prefijos o sufijos dinámicos.

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

**Ejemplo:**

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

Devuelve `true` porque `@external/BRL` existe dentro del valor de origen.

## Resumen de operadores y filtros

***

| Nombre               | Tipo     | Descripción                                 |
| -------------------- | -------- | ------------------------------------------- |
| `sum_by`             | Etiqueta | Suma valores por campo con filtro opcional  |
| `count_by`           | Etiqueta | Cuenta elementos con filtro opcional        |
| `avg_by`             | Etiqueta | Calcula el promedio por campo               |
| `min_by`             | Etiqueta | Encuentra el valor mínimo                   |
| `max_by`             | Etiqueta | Encuentra el valor máximo                   |
| `date_time`          | Etiqueta | Da formato a la fecha/hora actual           |
| `calc`               | Etiqueta | Evalúa expresiones aritméticas              |
| `last_item_by_group` | Etiqueta | Elemento más reciente por grupo según fecha |
| `counter`            | Etiqueta | Incrementa un contador con nombre           |
| `counter_show`       | Etiqueta | Muestra el valor de los contadores          |
| `percent_of`         | Filtro   | Calcula el porcentaje                       |
| `strip_zeros`        | Filtro   | Elimina los ceros finales                   |
| `slice`              | Filtro   | Extrae una subcadena                        |
| `replace`            | Filtro   | Reemplazo de cadenas                        |
| `where`              | Filtro   | Filtra un array por valor de campo          |
| `sum`                | Filtro   | Suma los valores de un campo del array      |
| `count`              | Filtro   | Cuenta los elementos coincidentes           |
| `contains`           | Función  | Coincidencia parcial de cadenas             |
| `floatformat`        | Filtro   | Da formato a los decimales                  |

<h2 id="advanced-filtering">
  Filtrado avanzado
</h2>

***

Al generar un informe, puedes pasar filtros en el cuerpo de la solicitud para acotar los datos. Los filtros siguen una estructura de fuente de datos > tabla > campo:

**Esquema único (predeterminado):**

```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"] }
      }
    }
  }
}
```

**Multiesquema (clave explícita schema.table):**

```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 admitidos:**

| Operador  | Descripción                          | Ejemplo                              |
| --------- | ------------------------------------ | ------------------------------------ |
| `eq`      | Igual a                              | `{ "eq": ["active", "pending"] }`    |
| `gt`      | Mayor que                            | `{ "gt": [100] }`                    |
| `gte`     | Mayor o igual que                    | `{ "gte": ["2025-06-01"] }`          |
| `lt`      | Menor que                            | `{ "lt": [1000] }`                   |
| `lte`     | Menor o igual que                    | `{ "lte": ["2025-06-30"] }`          |
| `between` | El valor está dentro de un rango     | `{ "between": [100, 1000] }`         |
| `in`      | El valor está dentro de una lista    | `{ "in": ["active", "pending"] }`    |
| `nin`     | El valor no está dentro de una lista | `{ "nin": ["deleted", "archived"] }` |
