Saltar al contenido principal
Este ejemplo muestra cómo estructurar un Reporte Financiero Analítico enfocado en el análisis de transacciones a nivel de cuenta, en formato HTML. El reporte incluye:
  • Información de Organización y Libro Contable.
  • Desglose por cuenta.
  • Lista detallada de operaciones.

Código de plantilla


<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title>Informe Financiero Analítico</title>
  <style>
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: #f4f6f9;
      color: #333;
      padding: 40px;
    }

    .container {
      max-width: 900px;
      margin: auto;
      background: #ffffff;
      padding: 30px 40px;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0,0,0,0.1);
    }

    h1 {
      text-align: center;
      font-size: 24px;
      color: #004080;
      margin-bottom: 10px;
    }

    .subtitle {
      text-align: center;
      font-size: 14px;
      color: #777;
      margin-bottom: 30px;
    }

    .section-title {
      font-weight: bold;
      font-size: 16px;
      margin-top: 30px;
      margin-bottom: 10px;
      color: #004080;
      border-bottom: 1px solid #ccc;
      padding-bottom: 4px;
    }

    table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 15px;
    }

    th, td {
      padding: 10px;
      text-align: left;
      border: 1px solid #ccc;
    }

    th {
      background-color: #e8f0fe;
      font-weight: bold;
      color: #003366;
    }

    .info p {
      margin: 4px 0;
    }

    .footer {
      margin-top: 40px;
      text-align: center;
      font-size: 12px;
      color: #999;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>Informe Financiero Analítico</h1>
    <div class="subtitle">Análisis detallado de los movimientos por cuentas vinculadas.</div>

    <div class="info">
      <p><strong>Fecha de Generación:</strong> {% date_time "dd/MM/YYYY HH:mm" %}</p>
      <p><strong>Organización:</strong> {{ midaz_onboarding.organization.0.legal_name }}</p>
      <p><strong>Ledger:</strong> {{ midaz_onboarding.ledger.0.name }}</p>
    </div>

    {% for account in midaz_onboarding.account %}
      {% with balance = filter(midaz_transaction.balance, "account_id", account.id)[0] %}
        <div class="section-title">Cuenta: {{ account.alias }}</div>
        <div class="info">
          <p><strong>ID:</strong> {{ account.id }}</p>
          <p><strong>Moneda:</strong> {{ balance.asset_code }}</p>
          <p><strong>Saldo Actual:</strong> {{ balance.available }}</p>
        </div>

        <table>
          <thead>
            <tr>
              <th>ID de la Operación</th>
              <th>Tipo</th>
              <th>Importe Original</th>
              <th>Descuento (3%)</th>
              <th>Importe Final</th>
              <th>Descripción</th>
            </tr>
          </thead>
          <tbody>
            {% for operation in midaz_transaction.operation %}
              {% if operation.account_id == account.id %}
                {% set original_amount = operation.amount %}
                {% set discount_amount = original_amount * 0.03  %}
                {% set final_amount = original_amount - discount_amount %}
                <tr>
                  <td>{{ operation.id }}</td>
                  <td>{{ operation.type }}</td>
                  <td>{{ original_amount|floatformat:2 }}</td>
                  <td>{{ discount_amount|floatformat:2 }}</td>
                  <td>{{ final_amount|floatformat:2 }}</td>
                  <td>{{ operation.description }}</td>
                </tr>
              {% endif %}
            {% endfor %}
          </tbody>
        </table>
      {% endwith %}
    {% endfor %}

    <div class="footer">
      Documento generado automáticamente a través de Reporter - Lerian · {{ midaz_onboarding.organization.0.legal_document }}
    </div>
  </div>
</body>
</html>

Desglose del código


Información de Organización y Libro Contable

    <div class="info">
      <p><strong>Fecha de Generación:</strong> {% date_time "dd/MM/YYYY HH:mm" %}</p>
      <p><strong>Organización:</strong> {{ midaz_onboarding.organization.0.legal_name }}</p>
      <p><strong>Ledger:</strong> {{ midaz_onboarding.ledger.0.name }}</p>
    </div>
<p><strong>Fecha de Generación:</strong> {% date_time "dd/MM/YYYY HH:mm" %}</p> Esta función aplica la fecha y hora cuando se renderiza la plantilla, usando el formato dd/MM/YYYY HH:mm. <p><strong>Organización:</strong> {{ midaz_onboarding.organization.0.legal_name }}</p> Esta línea renderiza el nombre legal de la primera Organización asociada con los datos de onboarding.
  • midaz_onboarding.organization: la lista de Organizaciones en el sistema.
  • 0: obtiene el primer elemento de la lista.
  • legal_name: obtiene el valor del campo legal_name.
<p><strong>Ledger:</strong> {{ midaz_onboarding.ledger.0.name }}</p> Esta línea renderiza el nombre del primer Libro Contable asociado con los datos de onboarding.
  • midaz_onboarding.ledger: la lista de Libros Contables en el sistema.
  • 0: obtiene el primer elemento de la lista.
  • name: obtiene el valor del campo name.

Iterando a través de las cuentas

    {% for account in midaz_onboarding.account %}
      {% with balance = filter(midaz_transaction.balance, "account_id", account.id)[0] %}  
{% for account in midaz_onboarding.account %} Este bucle recorre cada cuenta en la lista midaz_onboarding.account.
  • Esta lista representa todas las cuentas vinculadas a un cliente o asociadas con un flujo de onboarding.
  • Para cada iteración, crea un nuevo alcance donde account se refiere a un elemento específico en esa lista.
{% with balance = filter(midaz_transaction.balance, "account_id", account.id)[0] %} Dentro del bucle, esta línea:
  • Usa la función filter para encontrar un saldo de la lista midaz_transaction.balance donde el account_id coincida con el ID de la cuenta actual.
  • El [0] obtiene el primer saldo coincidente (asumiendo que solo hay uno por cuenta).
  • El resultado se almacena en una variable temporal llamada balance, con alcance solo dentro de este bloque.

Información de la cuenta

        <div class="section-title">Account: {{ account.alias }}</div>
        <div class="info">
          <p><strong>ID:</strong> {{ account.id }}</p>
          <p><strong>Moneda:</strong> {{ balance.asset_code }}</p>
          <p><strong>Saldo Actual:</strong> {{ balance.available }}</p>
        </div>
<div class="section-title">Cuenta: {{ account.alias }}</div> Muestra un título de sección con el alias de la cuenta (un nombre amigable o legible para la cuenta). <p><strong>ID:</strong> {{ account.id }}</p> Muestra el identificador único de la cuenta. <p><strong>Moneda:</strong> {{ balance.asset_code }}</p> Muestra el código de moneda (como “BRL” o “USD”) asociado con el saldo de la cuenta. <p><strong>Saldo Actual:</strong> {{ balance.available }} Muestra el saldo disponible actual.

Información de operaciones

            {% for operation in midaz_transaction.operation %}
              {% if operation.account_id == account.id %}
                {% set original_amount = operation.amount %}
                {% set discount_amount = original_amount * 0.03  %}
                {% set final_amount = original_amount - discount_amount %}
{% for operation in midaz_transaction.operation %} Este bucle recorre todas las operaciones de la lista midaz_transaction.operation. {% if operation.account_id == account.id %} Esta línea verifica si la operación actual está relacionada con la cuenta actual en el bucle externo (de tu bloque anterior) y solo procede si:
  • El account_id de la operación coincide con el account.id en foco.
{% set original_amount = operation.amount %} Esta línea establece una variable temporal llamada original_amount y le da el valor del campo amount en el objeto de operación. {% set discount_amount = original_amount * 0.03 %} Esta línea calcula un descuento del 3% sobre el monto original.
  • El resultado se guarda como discount_amount.
{% set final_amount = original_amount - discount_amount %} Esta línea resta el descuento del monto original.
  • El resultado final se almacena en final_amount, que puede renderizarse más tarde.

Columnas de la tabla

                <tr>
                  <td>{{ operation.id }}</td>
                  <td>{{ operation.type }}</td>
                  <td>{{ original_amount|floatformat:2 }}</td>
                  <td>{{ discount_amount|floatformat:2 }}</td>
                  <td>{{ final_amount|floatformat:2 }}</td>
                  <td>{{ operation.description }}</td>
                </tr>
Este bloque genera una fila de tabla limpia y legible para cada operación, incluyendo la siguiente información: <td>{{ operation.id }}</td> Identificador único de la operación. <td>{{ operation.type }}</td> Tipo de operación, como credit o debit. <td>{{ original_amount|floatformat:2 }}</td> Muestra el monto original (sin ajustar), formateado con 2 decimales. <td>{{ discount_amount|floatformat:2 }}</td> Muestra el descuento calculado, también con 2 decimales. <td>{{ final_amount|floatformat:2 }}</td> Muestra el monto final después de aplicar el descuento del 3%, bien formateado. <td>{{ operation.description }}</td> Renderiza la descripción o etiqueta de la operación, como “Transferencia a ahorros”.

Pie de página del reporte

    <div class="footer">
      Documento generado automáticamente a través de Reporter - Lerian · {{ midaz_onboarding.organization.0.legal_document }}
    </div>
Esta línea renderiza un pie de página en la parte inferior del documento, indicando que el contenido fue generado automáticamente usando Reporter de Lerian.
  • También incluye el número de documento legal de la primera organización vinculada a los datos de onboarding, extraído dinámicamente usando el marcador de posición {{ midaz_onboarding.organization.0.legal_document }}.

Salida de la plantilla


<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title>Informe Financiero Analítico</title>
  <style>
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: #f4f6f9;
      color: #333;
      padding: 40px;
    }

    .container {
      max-width: 900px;
      margin: auto;
      background: #ffffff;
      padding: 30px 40px;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0,0,0,0.1);
    }

    h1 {
      text-align: center;
      font-size: 24px;
      color: #004080;
      margin-bottom: 10px;
    }

    .subtitle {
      text-align: center;
      font-size: 14px;
      color: #777;
      margin-bottom: 30px;
    }

    .section-title {
      font-weight: bold;
      font-size: 16px;
      margin-top: 30px;
      margin-bottom: 10px;
      color: #004080;
      border-bottom: 1px solid #ccc;
      padding-bottom: 4px;
    }

    table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 15px;
    }

    th, td {
      padding: 10px;
      text-align: left;
      border: 1px solid #ccc;
    }

    th {
      background-color: #e8f0fe;
      font-weight: bold;
      color: #003366;
    }

    .info p {
      margin: 4px 0;
    }

    .footer {
      margin-top: 40px;
      text-align: center;
      font-size: 12px;
      color: #999;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>Informe Financiero Analítico</h1>
    <div class="subtitle">Análisis detallado de los movimientos por cuentas vinculadas.</div>

    <div class="info">
      <p><strong>Fecha de Generación:</strong> 23/05/2025 14:08</p>
      <p><strong>Organización:</strong> Mante - Pfannerstill</p>
      <p><strong>Ledger:</strong> Rice, Rowe and O'Hara</p>
    </div>    
        <div class="section-title">Cuenta: @external/USD</div>
        <div class="info">
          <p><strong>ID:</strong> 0196d97e-a58d-7814-8eb3-e510b818f6a5</p>
          <p><strong>Moneda:</strong> USD</p>
          <p><strong>Saldo Actual:</strong> 499950.00</p>
        </div>

        <table>
          <thead>
            <tr>
              <th>ID de la Operación</th>
              <th>Tipo</th>
              <th>Importe Original</th>
              <th>DiscoDescuentount (3%)</th>
              <th>Importe Final</th>
              <th>Descripción</th>
            </tr>
          </thead>
          <tbody>            
                <tr>
                  <td>0196d982-4085-7e1d-b698-3aad306df721</td>
                  <td>CREDIT</td>
                  <td>500000.00</td>
                  <td>15000.00</td>
                  <td>485000.00</td>
                  <td>Prueba de cuenta duplicada</td>
                </tr>
                <tr>
                  <td>0196d983-a2c2-7dce-ad14-78eb36d9f2d1</td>
                  <td>DEBIT</td>
                  <td>20.00</td>
                  <td>0.60</td>
                  <td>19.40</td>
                  <td>Persona 1 que paga el préstamo</td>
                </tr>
                <tr>
                  <td>0196d983-a2c2-7e0d-a246-45d5234138e3</td>
                  <td>DEBIT</td>
                  <td>30.00</td>
                  <td>0.90</td>
                  <td>29.10</td>
                  <td>Persona 2 que paga el préstamo</td>
                </tr>
          </tbody>
        </table>      
    <div class="footer">
      Documento generado automáticamente a través de Reporter - Lerian· 123.456.789-0001/00
    </div>
  </div>
</body>
</html>

Salida renderizada


Figura 1. Un ejemplo de un reporte financiero renderizado desde el código HTML en el ejemplo.