> ## 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 4010 y 4016

> Genera los reportes XML CADOC 4010 y 4016 para BACEN con Reporter, siguiendo el estándar COSIF y el layout regulatorio requerido.

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 los informes **CADOC 4010** y **CADOC 4016** 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é son CADOC 4010 y 4016?

***

El **4010** y el **4016** son informes de Balance Analítico utilizados para enviar informes financieros al **BACEN** (Banco Central de Brasil).

### Lo que BACEN espera recibir

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

### Diferencia entre CADOC 4010 y 4016

| Documento | Periodicidad        | Fecha Base | Cuentas Esperadas                  |
| --------- | ------------------- | ---------- | ---------------------------------- |
| **4010**  | Mensual             | AAAA-MM    | Todas las cuentas                  |
| **4016**  | Semestral (Jun/Dic) | AAAA-MM    | Sin grupos 7 y 8 (Ingresos/Gastos) |

El **4016** representa la posición contable de la entidad después del cierre del estado de resultados. En este punto, las cuentas de Ingresos (grupo 7) y las cuentas de Gastos (grupo 8) ya han sido cerradas y sus saldos transferidos al Patrimonio.

### Requisitos de envío

| Documento | Plazo                                               | Código STA |
| --------- | --------------------------------------------------- | ---------- |
| **4010**  | Día 18 del mes siguiente (o el siguiente día hábil) | ACOS010    |
| **4016**  | Último día hábil del mes siguiente                  | ACOS016    |

<Note>
  El código STA identifica el tipo de documento en el sistema de transmisión de BACEN. Usa `ACOS010` al enviar CADOC 4010 y `ACOS016` al enviar CADOC 4016.
</Note>

## Entendiendo la estructura de datos

***

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

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

### Operaciones

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

* **Cuenta asociada (`account_id`)**: Qué cuenta fue movida
* **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

### Relación entre entidades

<Frame>
  <img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/es/d2/cadoc-4010-4016-structure.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=cf7a61445d2b10b3e36f2924749a2dbc" alt="Relación entre las entidades del ledger y las operaciones que se usan para construir los informes CADOC 4010 y 4016" width="772" height="382" data-path="images/es/d2/cadoc-4010-4016-structure.svg" />
</Frame>

<Info>
  La entidad `balance` representa el saldo **actual** de la cuenta, no el historial. Para informes regulatorios que necesitan saldos de un período específico, usa la entidad `operation` con filtros de fecha.
</Info>

## 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="4010" cnpj="99999999" dataBase="2025-11" tipoRemessa="I">
    <contas>
      <conta codigoConta="1000000009" saldo="99.99" />
      <conta codigoConta="1100000002" saldo="99.99" />
    </contas>
  </documento>
  ```
</CodeGroup>

### Campos obligatorios

**`<?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          | `"4010"` o `"4016"`    |
| `cnpj`            | Primeros 8 dígitos del CNPJ | Numérico, 8 posiciones |
| `dataBase`        | Mes 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 de cuenta, siguiendo el formato COSIF (10 dígitos numéricos).
* `saldo`: Saldo de la cuenta 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, agregar los saldos de las operaciones vinculadas

### Iterando sobre rutas

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

1. **Verificar si tiene código COSIF**: Solo las rutas con código completo generan líneas
2. **Filtrar operaciones**: Seleccionar operaciones que pertenecen a esa ruta
3. **Calcular el saldo**: Agregar los saldos de las operaciones filtradas

### Precaución con nomenclatura de variables

Al construir la plantilla, evita usar el mismo nombre para la variable de iteración y el campo de filtro:

| Enfoque        | Ejemplo                                       | Resultado              |
| -------------- | --------------------------------------------- | ---------------------- |
| **Incorrecto** | `for route in ... if route == route.id`       | Conflicto de nombres   |
| **Correcto**   | `for op_route in ... if route == op_route.id` | Funciona correctamente |

## Plantilla CADOC 4010

***

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

<CodeGroup>
  ```xml tpl theme={null}
  <?xml version="1.0" encoding="UTF-8"?>
  <documento codigoDocumento="4010" 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 }}" saldo="{% sum_by midaz_transaction.operation by "available_balance_after" if route == op_route.id %}" />
  {%- endif %}
  {%- endfor %}
    </contas>
  </documento>
  ```
</CodeGroup>

### Explicación línea por línea

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

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

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

* `codigoDocumento="4010"`: Identificador fijo para el Balance Analítico
* `cnpj`: Extrae los primeros 8 dígitos del documento legal de la organización
* `dataBase`: Genera la fecha en formato AAAA-MM (mes de referencia)
* `tipoRemessa="I"`: Indica inclusión de datos

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

* `op_route`: Variable que recibe cada ruta durante la iteración
* `midaz_transaction.operation_route`: Colección de todas las rutas de operación

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

Verifica si la ruta tiene un código COSIF completo.

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

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

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

Cierran la condición y el bucle respectivamente.

### Etiquetas y filtros utilizados

| 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    | Corta los primeros 8 caracteres               |
| `for ... in`           | Etiqueta  | Itera a través de una colección               |
| `if`                   | Etiqueta  | Condición para ejecución                      |
| `sum_by ... by ... if` | Etiqueta  | Suma valores con filtro condicional           |
| `date_time`            | Etiqueta  | Genera fecha formateada                       |

## Plantilla CADOC 4016

***

El CADOC 4016 es el Balance Analítico, similar al 4010, pero con periodicidad semestral y una restricción importante: **no debe contener cuentas de los grupos 7 (Ingresos) y 8 (Gastos)**.

### ¿Por qué excluir los grupos 7 y 8?

El documento 4016 representa la posición contable de la entidad **después del cierre del estado de resultados**. En este punto, las cuentas de Ingresos (grupo 7) y las cuentas de Gastos (grupo 8) ya han sido cerradas y sus saldos transferidos al Patrimonio.

### Ejemplo de plantilla

<CodeGroup>
  ```xml tpl theme={null}
  <?xml version="1.0" encoding="UTF-8"?>
  <documento codigoDocumento="4016" 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 and op_route.code|slice:":1" != "7" and op_route.code|slice:":1" != "8" %}
      <conta codigoConta="{{ op_route.code }}" saldo="{% sum_by midaz_transaction.operation by "available_balance_after" if route == op_route.id %}" />
  {%- endif %}
  {%- endfor %}
    </contas>
  </documento>
  ```
</CodeGroup>

### Diferencia con 4010

La única diferencia en la plantilla es la condición adicional en el `if`:

| Plantilla | Condición                                                                                    |
| --------- | -------------------------------------------------------------------------------------------- |
| **4010**  | `if op_route.code`                                                                           |
| **4016**  | `if op_route.code and op_route.code\|slice:":1" != "7" and op_route.code\|slice:":1" != "8"` |

### Cómo funciona la exclusión

El filtro `slice:":1"` extrae el primer carácter del código COSIF:

| Código COSIF | Primer Dígito | Grupo    | ¿Incluido en 4016? |
| ------------ | ------------- | -------- | ------------------ |
| 1000000009   | 1             | Activos  | Sí                 |
| 2100000003   | 2             | Pasivos  | Sí                 |
| 7100000001   | 7             | Ingresos | **No**             |
| 8200000005   | 8             | Gastos   | **No**             |

## Generando el informe con filtro de fecha

***

### Ejemplo de solicitud para 4010

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

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

### Explicación de campos

| Campo                                 | Descripción                                                     |
| ------------------------------------- | --------------------------------------------------------------- |
| `templateId`                          | Identificador de la plantilla CADOC 4010 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]`                          | Primer día del mes a las 00:00:00 UTC                           |
| `between[1]`                          | Último día del mes a las 23:59:59 UTC                           |

**Formato de fecha**: ISO 8601 con zona horaria UTC (`Z`).

<Warning>
  Ajusta el último día según el mes (28, 29, 30 o 31 días).
</Warning>

### Ejemplo de solicitud para 4016

Para generar el CADOC 4016 para el primer semestre:

<CodeGroup>
  ```json JSON theme={null}
  {
    "templateId": "CADOC_4016_TEMPLATE_ID",
    "filters": {
      "midaz_transaction": {
        "operation": {
          "created_at": {
            "between": ["2025-01-01T00:00:00Z", "2025-06-30T23:59:59Z"]
          }
        }
      }
    }
  }
  ```
</CodeGroup>

Para el segundo semestre, ajusta las fechas de julio a diciembre.

## 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 4010/4016, que requiere el saldo final del último día hábil del mes.

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 4010/4016 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>
  ```xml tpl 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.

## Comparación con CADOC 4111

***

CADOC 4010 y CADOC 4111 comparten la misma estructura de plantilla, con diferencias solo en los parámetros:

| Aspecto           | CADOC 4111     | CADOC 4010      |
| ----------------- | -------------- | --------------- |
| Documento         | Saldos Diarios | Balance Mensual |
| Periodicidad      | Diaria         | Mensual         |
| `codigoDocumento` | `"4111"`       | `"4010"`        |
| `dataBase`        | AAAA-MM        | AAAA-MM         |
| Filtro de fecha   | 1 día          | 1 mes           |
| Saldo esperado    | Último del día | Último del mes  |

**Plantilla idéntica**: La lógica para iterar sobre rutas y agregar saldos es la misma.

## 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 para 4010. 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).

### Código de cuenta COSIF

El plan de cuentas COSIF está estructurado con 6 niveles jerárquicos y un dígito verificador. El campo `codigoConta` debe tener 10 dígitos numéricos, sin puntos ni 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>
