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

# CADOC 4111

> Genera el reporte XML CADOC 4111 para BACEN con Reporter — saldos diarios de cuentas agrupados por código COSIF en el layout regulatorio.

Reporter te permite generar informes basados en XML que siguen la estructura oficial de CADOC, exactamente como lo requiere el Banco Central de Brasil (BACEN).

Esta guía te muestra la estructura y la lógica utilizada para generar el informe **CADOC 4111** en XML.

<Danger>
  Estos informes siguen el estándar **COSIF** y deben coincidir con la estructura XML definida por BACEN. Puedes adaptar la lógica a tu propio modelo de datos, pero el formato XML debe respetarse.
</Danger>

## ¿Qué es CADOC 4111?

***

El **CADOC 4111** es un documento regulatorio requerido por el Banco Central de Brasil (BACEN) que reporta saldos diarios de cuentas contables agrupados por código COSIF (Plan de Cuentas para Instituciones del Sistema Financiero Nacional).

### Lo que BACEN espera recibir

* Saldos consolidados por código COSIF
* Fecha base del informe
* CNPJ de la institución (primeros 8 dígitos)
* Tipo de envío (`I` = Inclusión, `S` = Sustitución)

### Requisitos de envío

| Documento | Plazo                                                          | Código STA |
| --------- | -------------------------------------------------------------- | ---------- |
| **4111**  | Día siguiente a la fecha de referencia (o siguiente día hábil) | ACOS011    |

<Note>
  El código STA identifica el tipo de documento en el sistema de transmisión de BACEN. Usa `ACOS011` al enviar CADOC 4111.
</Note>

## Entendiendo la estructura de datos

***

Antes de construir la plantilla, es esencial entender cómo se organizan los datos en el libro mayor de Midaz.

### Rutas de operación

Las rutas de operación funcionan como clasificadores contables. Cada ruta tiene:

* **Identificador único (`id`)**: Usado internamente para relacionar operaciones
* **Código COSIF (`code`)**: El código contable de 10 dígitos que será reportado a BACEN

Cuando se registra una operación en Midaz, se asocia con una ruta. Esta ruta contiene el código COSIF correspondiente.

<Tip>
  Piensa en las rutas como "etiquetas contables" adjuntas a cada operación, indicando bajo qué categoría del plan de cuentas debe clasificarse ese movimiento.
</Tip>

### Operaciones

Las operaciones representan movimientos financieros en el libro mayor. Cada operación contiene:

* **Cuenta asociada (`account_id`)**: Qué cuenta fue afectada
* **Ruta (`route`)**: ID de la ruta/clasificación contable aplicada
* **Saldo después de la operación (`available_balance_after`)**: El saldo de la cuenta inmediatamente después de esta operación
* **Fecha y hora (`created_at`)**: Cuándo ocurrió la operación

<Warning>
  El campo de saldo después de la operación representa el saldo acumulado de la cuenta en ese momento, no el valor de la operación en sí.
</Warning>

### Relación entre rutas y operaciones

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/es/d2/cadoc-4111-structure.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=ac366faa632ec3fc243c0b73fd0600de" alt="Relación entre las rutas contables y las operaciones que se usan para construir el informe CADOC 4111" width="1030" height="466" data-path="images/es/d2/cadoc-4111-structure.svg" />
</Frame>

Cada ruta puede tener múltiples operaciones vinculadas a lo largo del día.

## Estructura de CADOC

***

### Formato base

El informe CADOC **debe** ser un archivo XML y **debe** seguir la estructura definida por **BACEN**:

<CodeGroup>
  ```xml XML theme={null}
  <?xml version="1.0" encoding="UTF-8"?>
  <documento codigoDocumento="4111" cnpj="99999999" dataBase="2025-11" tipoRemessa="I">
    <contas>
      <conta codigoConta="1000000009" saldoDia="99.99" />
      <conta codigoConta="1100000002" saldoDia="99.99" />
    </contas>
  </documento>
  ```
</CodeGroup>

### Campos obligatorios

Estos campos son requeridos y deben incluirse:

**`<?xml version="1.0" encoding="UTF-8"?>`**

Siempre inicia el archivo. Define la versión de XML y la codificación para que el sistema sepa cómo leer el contenido.

**Etiqueta `<documento>`**

Envuelve toda la estructura CADOC e incluye:

| Campo             | Descripción                 | Formato                |
| ----------------- | --------------------------- | ---------------------- |
| `codigoDocumento` | Identificador fijo          | `"4111"`               |
| `cnpj`            | Primeros 8 dígitos del CNPJ | Numérico, 8 posiciones |
| `dataBase`        | Fecha de referencia         | AAAA-MM                |
| `tipoRemessa`     | Tipo de envío               | `"I"` o `"S"`          |

<Danger>
  Si tu primer envío fue rechazado debido a errores, aún necesitas usar `"I"` en tu próximo intento. Solo usa `"S"` para reemplazar datos previamente aprobados.
</Danger>

**Etiqueta `<contas>`**

Agrupa todas las entradas de cuentas para el período del informe.

**Etiqueta `<conta>`**

* `codigoConta`: Código COSIF de la ruta de operación (10 dígitos numéricos)
* `saldoDia`: Saldo consolidado en formato decimal (dos decimales)

## Lógica de construcción de la plantilla

***

### Estructura general

La plantilla sigue una lógica de agregación en dos niveles:

1. **Primer nivel**: Iterar a través de todas las rutas de operación disponibles
2. **Segundo nivel**: Para cada ruta, sumar los saldos de las operaciones vinculadas

### Encabezado del documento

El encabezado XML debe contener:

* **Código del documento**: Identificador fijo `4111`
* **CNPJ**: Extraído de los datos de la organización, limitado a los primeros 8 dígitos
* **Fecha base**: Fecha de generación del informe en formato `AAAA-MM`
* **Tipo de envío**: `I` para inclusión

Los datos de la organización se obtienen de la fuente de datos de onboarding de Midaz, específicamente de la entidad organización.

### Iterando sobre rutas

La plantilla debe iterar a través de todas las rutas de operación registradas. Para cada ruta:

1. **Verificar código COSIF**: Solo las rutas con un código COSIF válido deben generar líneas en el informe
2. **Filtrar operaciones**: Seleccionar solo las operaciones que pertenecen a esa ruta específica
3. **Calcular saldo**: Sumar los saldos de las operaciones filtradas

<Info>
  No todas las rutas tienen un código COSIF completo. Las rutas sin código se usan para controles internos y no deben aparecer en el informe regulatorio.
</Info>

### Filtrando operaciones por ruta

La asociación entre operaciones y rutas se realiza a través del identificador de ruta. La plantilla usa este identificador para:

1. Acceder a una ruta específica
2. Encontrar todas las operaciones que referencian esta ruta
3. Procesar solo estas operaciones en la agregación

<Warning>
  Al construir la plantilla, evita usar el mismo nombre para la variable de iteración y el campo de filtro, ya que esto puede causar conflictos en la interpretación de la plantilla.
</Warning>

### Sumando saldos

Para cada conjunto de operaciones de una ruta, la plantilla suma los saldos disponibles. El campo utilizado es el saldo disponible después de cada operación.

La función de agregación itera a través de todas las operaciones que cumplen los criterios de filtro (misma ruta) y acumula los valores del campo de saldo.

## Usando Reporter

***

Aquí está la plantilla completa para generar CADOC 4111 en Reporter:

<CodeGroup>
  ```tpl Plantilla theme={null}
  <?xml version="1.0" encoding="UTF-8"?>
  <documento codigoDocumento="4111" cnpj="{{ midaz_onboarding.organization.0.legal_document|slice:":8" }}" dataBase="{% date_time "YYYY-MM" %}" tipoRemessa="I">
    <contas>
  {%- for op_route in midaz_transaction.operation_route %}
  {%- if op_route.code %}
      <conta codigoConta="{{ op_route.code }}" saldoDia="{% sum_by midaz_transaction.operation by "available_balance_after" if route == op_route.id %}" />
  {%- endif %}
  {%- endfor %}
    </contas>
  </documento>
  ```
</CodeGroup>

## Desglose del código

***

### Línea 1 - Declaración XML

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
```

Encabezado XML estándar con codificación UTF-8.

### Línea 2 - Elemento raíz `<documento>`

```tpl theme={null}
<documento codigoDocumento="4111" cnpj="{{ midaz_onboarding.organization.0.legal_document|slice:":8" }}" dataBase="{% date_time "YYYY-MM" %}" tipoRemessa="I">
```

* `codigoDocumento="4111"`: Identificador fijo del tipo de documento
* `cnpj`: Accede al documento legal de la organización y extrae los primeros 8 caracteres usando el filtro `slice`
* `dataBase`: Genera la fecha actual en el formato requerido por BACEN usando la etiqueta `date_time`
* `tipoRemessa="I"`: Indica inclusión de datos

### Línea 4 - Inicio del bucle `for`

```tpl theme={null}
{%- for op_route in midaz_transaction.operation_route %}
```

* `op_route`: Variable que recibe cada ruta durante la iteración (nombre elegido para evitar conflicto con el campo `route` en operaciones)
* `midaz_transaction.operation_route`: Colección de todas las rutas de operación

### Línea 5 - Condición `if`

```tpl theme={null}
{%- if op_route.code %}
```

Verifica si la ruta tiene un código COSIF completo. Las rutas sin código son ignoradas.

### Línea 6 - Elemento `<conta>`

```tpl theme={null}
<conta codigoConta="{{ op_route.code }}" saldoDia="{% sum_by midaz_transaction.operation by "available_balance_after" if route == op_route.id %}" />
```

* `codigoConta`: Muestra el código COSIF de la ruta actual
* `saldoDia`: Usa la etiqueta `sum_by` para sumar saldos, filtrando solo las operaciones cuya ruta coincide con el identificador de la ruta actual (`op_route.id`)

### Líneas 7-8 - Cierre de bloques

```tpl theme={null}
{%- endif %}
{%- endfor %}
```

Cierran la condición y el bucle respectivamente.

### Referencia de etiquetas y filtros

| Elemento               | Tipo      | Función                                       |
| ---------------------- | --------- | --------------------------------------------- |
| `{{ variable }}`       | Expresión | Muestra el valor de una variable              |
| `{% tag %}`            | Etiqueta  | Ejecuta lógica (bucle, condición, agregación) |
| `\|slice:":8"`         | Filtro    | Extrae los primeros 8 caracteres              |
| `for ... in`           | Etiqueta  | Itera a través de una colección               |
| `if`                   | Etiqueta  | Condición de ejecución                        |
| `sum_by ... by ... if` | Etiqueta  | Suma valores con filtro condicional           |
| `date_time`            | Etiqueta  | Genera fecha formateada                       |

## Consideraciones del filtro de fecha

***

### Ejemplo de solicitud con filtro de fecha

Para generar CADOC 4111 para un día específico, envía una solicitud `POST /v1/reports` con el encabezado `X-Organization-Id` y el siguiente cuerpo:

<CodeGroup>
  ```json Solicitud theme={null}
  {
    "templateId": "CADOC_4111_TEMPLATE_ID",
    "filters": {
      "midaz_transaction": {
        "operation": {
          "created_at": {
            "between": ["2025-11-11T00:00:00Z", "2025-11-11T23:59:59Z"]
          }
        }
      }
    }
  }
  ```
</CodeGroup>

### Explicación de campos

| Campo                                 | Descripción                                                     |
| ------------------------------------- | --------------------------------------------------------------- |
| `templateId`                          | Identificador de la plantilla CADOC 4111 registrada en Reporter |
| `filters.midaz_transaction.operation` | Indica que el filtro se aplicará a la colección de operaciones  |
| `created_at.between`                  | Filtra operaciones creadas dentro del intervalo especificado    |
| `between[0]`                          | Fecha y hora de inicio (medianoche del día deseado)             |
| `between[1]`                          | Fecha y hora de fin (último segundo del día deseado)            |

<Info>
  Las fechas deben estar en formato ISO 8601 con zona horaria UTC (`Z`).
</Info>

## Evolución de la plantilla y extracción de saldos

***

Estamos trabajando en la evolución de nuestra plantilla principal para soportar la agregación de saldos en cumplimiento con BACEN CADOC 4111, que requiere el saldo final del último día hábil.

Mientras esta funcionalidad está siendo desarrollada, proporcionamos una versión alternativa para extraer estos saldos usando la siguiente plantilla.

### Plantilla de extracción

Esta plantilla auxiliar está diseñada para calcular correctamente los saldos, asegurando el cumplimiento de tus informes a través de los siguientes pasos:

1. Agrupar operaciones por cuenta
2. Ordenar entradas por fecha y hora
3. Seleccionar el último registro de cada cuenta para obtener el saldo final
4. Sumar saldos finales por código COSIF

Con esta opción, puedes extraer la información requerida para CADOC 4111 y transferirla al formato de diseño requerido por BACEN. Esta plantilla puede ayudar si ya tienes un proveedor que construye archivos CADOC.

### Ejemplo de plantilla de extracción

<CodeGroup>
  ```tpl Extracción CSV theme={null}
  account_id;account_alias;codigo_cosif;created_at;saldo_disponivel
  {%- for op_route in midaz_transaction.operation_route %}
  {%- if op_route.code %}
  {%- for op in filter(midaz_transaction.operation, "route", op_route.id) %}
  {{ op.account_id }};{{ op.account_alias }};{{ op_route.code }};{{ op.created_at }};{{ op.available_balance_after }}
  {%- endfor %}
  {%- endif %}
  {%- endfor %}
  ```
</CodeGroup>

### Salida de extracción

La plantilla exporta todas las operaciones en formato CSV, conteniendo:

* Identificador de cuenta
* Alias de cuenta
* Código COSIF
* Fecha y hora de la operación
* Saldo disponible

Puedes importar este CSV en una hoja de cálculo o tu sistema de conciliación existente para procesar los saldos finales.

## Mejores prácticas para construcción de plantillas

***

### Nomenclatura de variables

Usa nombres descriptivos y únicos para las variables de iteración, evitando conflictos con los nombres de campos de entidades.

### Validación de campos

Siempre verifica si los campos opcionales tienen valores antes de usarlos. Los campos vacíos pueden generar líneas no deseadas en el informe.

### Formato de fecha

BACEN requiere fechas en formato `AAAA-MM`. Asegúrate de configurar el formato correctamente en la plantilla.

### Manejo de CNPJ

El CNPJ debe presentarse con solo los primeros 8 dígitos, sin formato (puntos, barras o guiones).

## Resumen de componentes

***

| Componente   | Fuente de Datos                 | Uso en Plantilla         |
| ------------ | ------------------------------- | ------------------------ |
| CNPJ         | Organización (Onboarding)       | Encabezado del documento |
| Código COSIF | Ruta de Operación (Transacción) | Identificador de cuenta  |
| Saldo        | Operación (Transacción)         | Valor a agregar          |
| Fecha Base   | Función de fecha actual         | Encabezado del documento |

<Warning>
  Siempre valida el XML renderizado contra el esquema de BACEN antes de enviar. La estructura por sí sola no es suficiente — los datos deben reflejar el libro mayor real de tu institución.
</Warning>
