Skip to content

Manual del Servicio de Documentos de Kuenta ​

Este documento explica el servicio de documentos en Kuenta, incluyendo su uso de plantillas, variables disponibles y las funciones específicas que ofrece.

Descripción General ​

El servicio de documentos gestiona la creación, procesamiento y visualización de documentos en la plataforma Kuenta. Los documentos pueden ser creados, personalizados con plantillas, firmados y compartidos con diferentes partes.

Estructura de Datos ​

Documento ​

go
type Document struct {
    ID              uuid.UUID
    Title           string
    Body            string // Contenido HTML
    BodyText        string // Contenido texto plano
    Status          DocumentStatus
    CreditorID      uuid.UUID // ID de la organización acreedora
    Template        *Template
    PDFFileID       uuid.UUID // ID del archivo PDF generado
    Hash            string    // Hash del documento
    EnvelopeHash    string    // Hash del sobre que contiene este documento
    Attachments     *DocumentAttachments
    Credits         []*Credit
    SignatureRequests []*SignatureRequest
    Signatures      []*Signature
    CustomTemplate  string    // Plantilla personalizada
}

Variables Disponibles en Plantillas ​

El servicio de documentos proporciona las siguientes variables principales para usar en las plantillas:

txt
.Document         - El documento actual
.Template         - La plantilla del documento
.Title            - Título del documento
.Body             - Cuerpo del documento como HTML
.Creditor         - Organización acreedora
.Party            - Parte involucrada
.Signatures       - Firmas asociadas al documento

Datos de Crédito ​

Cuando el documento está relacionado con un crédito, tienes acceso al objeto Credit con toda la información:

txt
.Credit.ID                  - ID del crédito
.Credit.Status              - Estado del crédito
.Credit.Amount              - Monto del crédito
.Credit.Principal           - Monto principal del crédito
.Credit.Rate                - Tasa de interés
.Credit.Term                - Plazo del crédito
.Credit.Frequency           - Frecuencia de pago
.Credit.CreatedAt           - Fecha de creación
.Credit.UpdatedAt           - Fecha de actualización
.Credit.StartDate           - Fecha de inicio
.Credit.ApprovedAt          - Fecha de aprobación
.Credit.Debtor              - Objeto del deudor
.Credit.Creditor            - Objeto del acreedor
.Credit.Installments        - Cuotas del crédito

Funciones de Plantillas ​

Funciones Nativas de Go Templates ​

Las plantillas de documentos soportan todas las funciones estándar de Go Templates:

txt
{ { if }}...{ { else }}...{ { end }}   - Condiciones
{ { range .Items }}...{ { end }}      - Ciclos
{ { with .Object }}...{ { end }}      - Establecer contexto
{ { index .Array 1 }}                - Acceso a índice de array
{ { .Field }}                        - Acceso a campo

Biblioteca Sprig ​

El servicio de documentos incorpora completamente la biblioteca Sprig para procesamiento de plantillas. Según el análisis del código fuente en document_service.go, el método Parse() utiliza explícitamente:

go
sprigFunctions := sprig.FuncMap()
tmplBody, err := template.New("test").Funcs(sprigFunctions).Funcs(functions).Funcs(domain.ConfigurationFuncs(cfg)).Funcs(d.FuncsDocumentSrv(cfg)).Parse(documentCopy.Template.Body)

Esto significa que todas las funciones de Sprig están disponibles en las plantillas de documentos, ofreciendo más de 70 funciones para manipulación de datos, fechas, strings, matemáticas y más:

txt
{ { dict "key" "value" }}            - Crear diccionario
{ { get $dict "key" }}               - Obtener valor de diccionario
{ { toJson . }}                      - Convertir objeto a JSON
{ { fromJson . }}                    - Convertir JSON a objeto
{ { trim " text " }}                 - Eliminar espacios
{ { lower "TEXT" }}                  - Convertir a minúsculas
{ { upper "text" }}                  - Convertir a mayúsculas
{ { date_format "2006-01-02" .Date }} - Formatear fecha según patrón
{ { uuidv4 }}                        - Generar UUID v4
{ { add 1 2 }}                       - Suma de números
{ { sub 5 2 }}                       - Resta de números
{ { mul 2 3 }}                       - Multiplicación
{ { div 6 3 }}                       - División

Para una lista completa de todas las funciones disponibles en Sprig, consulte la documentación oficial de Sprig.

Funciones Específicas de Kuenta ​

Además de las funciones de Sprig, el servicio de documentos también incluye funciones específicas de Kuenta:

txt
{ { currency .Value }}               - Formatea un valor como moneda (Ej: $1,000,000)
{ { percentage .Value }}             - Formatea un valor como porcentaje (Ej: 12.5%)
{ { date .Credit.CreatedAt }}        - Formatea una fecha
{ { commonData .Profile "Name" }}    - Accede a datos comunes de un perfil
{ { decimalAdd .Value1 .Value2 }}    - Suma valores decimales
{ { customFields .Object.CustomFields "field_name" }} - Obtiene campo personalizado

Funciones Específicas del Servicio de Documentos ​

El servicio de documentos agrega funciones específicas a través de FuncsDocumentSrv():

txt
{ { signedAt .EntityID .TemplateID }} - Obtiene la fecha en que se firmó un documento
{ { currencyEntity .Value }}         - Formatea moneda según la configuración de la entidad
{ { incomes .Value }}                - Formatea ingresos según la configuración
{ { expenses .Value }}               - Formatea gastos según la configuración

Detalles de las Funciones Específicas ​

signedAt ​

Esta función obtiene la fecha en que se firmó un documento.

Sintaxis:

{ { signedAt .EntityID .TemplateID }}

Parámetros:

  • EntityID: El ID de la entidad que firmó el documento
  • TemplateID: El ID de la plantilla del documento

Retorno: Fecha formateada según el formato predeterminado del sistema (ej. "15/enero/2023")

Ejemplo:

html
<p>Este documento fue firmado el { { signedAt .Document.ID .Template.ID }}</p>
currencyEntity ​

Esta función formatea un valor numérico como moneda, utilizando la configuración específica de la entidad (símbolo, separadores, decimales).

Sintaxis: { { currencyEntity .Value }}

Parámetros:

  • Value: Valor numérico a formatear como moneda

Retorno: String formateado según la configuración de moneda de la entidad

Ejemplo:

html
<p>Monto total: { { currencyEntity .Credit.Amount }}</p>
<!-- Podría mostrar "$1,000,000" o "1.000.000 €" dependiendo de la configuración de la entidad -->
incomes ​

Esta función formatea un valor como ingresos según la configuración establecida para la entidad.

Sintaxis: { { incomes .Value }}

Parámetros:

  • Value: Valor numérico de ingresos a formatear

Retorno: String formateado según la configuración de la entidad para representar ingresos

Ejemplo:

html
<p>Ingresos mensuales: { { incomes .Credit.Debtor.Income }}</p>
expenses ​

Esta función formatea un valor como gastos según la configuración establecida para la entidad.

Sintaxis: { { expenses .Value }}

Parámetros:

  • Value: Valor numérico de gastos a formatear

Retorno: String formateado según la configuración de la entidad para representar gastos

Ejemplo:

html
<p>Gastos mensuales: { { expenses .Credit.Debtor.Expenses }}</p>

Funciones para Manipulación de Datos Complejos ​

El servicio de documentos también proporciona funciones avanzadas para acceder y manipular datos complejos:

references ​

Esta función formatea una lista de referencias.

Sintaxis: { { references .Profile.References }}

Ejemplo:

html
<div class="references">
  <h3>Referencias:</h3>
  { { references .Credit.Debtor.Profile.References }}
</div>
legalNested ​

Esta función permite acceder a datos anidados de entidades legales.

Sintaxis: { { legalNested .Profile.Legal.Representatives }}

Ejemplo:

html
<div class="representatives">
  <h3>Representantes Legales:</h3>
  { { legalNested .Credit.Debtor.Profile.Legal.Representatives }}
</div>
customFields ​

Esta función obtiene el valor de un campo personalizado de un objeto.

Sintaxis: { { customFields .Object.CustomFields "field_name" ["default_value"] }}

Parámetros:

  • CustomFields: Objeto que contiene los campos personalizados
  • field_name: Nombre del campo personalizado a obtener
  • default_value (opcional): Valor por defecto si el campo no existe

Ejemplo:

html
<p>
  Profesión: { { customFields .Credit.Debtor.Profile.CustomFields "profesion"
  "No especificada" }}
</p>
<p>
  Sector: { { customFields .Credit.Debtor.Profile.CustomFields
  "sector_economico" }}
</p>
allReferences ​

Esta función combina y formatea referencias personales, familiares y comerciales.

Sintaxis: { { allReferences .PersonalReferences .FamilyReferences .CommercialReferences }}

Ejemplo:

html
<div class="all-references">
  <h3>Todas las Referencias:</h3>
  { { allReferences .Credit.Debtor.PersonalReferences
  .Credit.Debtor.FamilyReferences .Credit.Debtor.CommercialReferences }}
</div>

Ejemplos de Uso de Plantillas ​

Ejemplo Básico ​

html
<h1>{ { .Title }}</h1>
<div class="content">{ { .Body }}</div>
<div class="footer">
  <p>Documento generado por { { .Creditor.Profile.Legal.Name }}</p>
  <p>Fecha: { { now | date_format "02/01/2006" }}</p>
</div>

Ejemplo de Contrato con Datos Dinámicos ​

html
<div class="contract">
  <h1>CONTRATO DE CRÉDITO</h1>

  <p>Entre los suscritos:</p>

  <p>
    <strong>{ { commonData .Creditor.Profile "Name" }}</strong>, identificado
    con { { .Creditor.IDType }} No. { { .Creditor.IDNumber }}, en calidad de
    ACREEDOR.
  </p>

  <p>Y</p>

  <p>
    <strong>{ { commonData .Credit.Debtor.Profile "Name" }}</strong>,
    identificado con { { .Credit.Debtor.Profile.Natural.IDType }} No. { {
    .Credit.Debtor.Profile.Natural.IDNumber }}, en calidad de DEUDOR.
  </p>

  <p>
    Hemos acordado celebrar el presente CONTRATO DE CRÉDITO, bajo las siguientes
    condiciones:
  </p>

  <p>
    <strong>PRIMERO. OBJETO:</strong> EL ACREEDOR otorga a EL DEUDOR un crédito
    por valor de { { currency .Credit.Amount }} que será pagado en { {
    .Credit.Term }} cuotas con una tasa de interés del { { percentage
    .Credit.Rate }}.
  </p>

  <p><strong>SEGUNDO. PLAN DE PAGOS:</strong></p>
  <table border="1">
    <tr>
      <th>No.</th>
      <th>Fecha</th>
      <th>Cuota</th>
      <th>Capital</th>
      <th>Interés</th>
    </tr>
    { { range $idx, $installment := .Credit.Installments }}
    <tr>
      <td>{ { add $idx 1 }}</td>
      <td>{ { $installment.Date | date }}</td>
      <td>{ { currency $installment.Payment }}</td>
      <td>{ { currency $installment.Principal }}</td>
      <td>{ { currency $installment.Interest }}</td>
    </tr>
    { { end }}
  </table>

  <p>Firmado en { { now | date }} por las partes:</p>

  <div class="signatures">
    <div class="signature">
      <p>ACREEDOR</p>
      <p>{ { commonData .Creditor.Profile "Name" }}</p>
    </div>

    <div class="signature">
      <p>DEUDOR</p>
      <p>{ { commonData .Credit.Debtor.Profile "Name" }}</p>
    </div>
  </div>
</div>

Ejemplo con Transformación de Datos y Diccionarios ​

html
<div class="financial-summary">
  <h2>Resumen Financiero</h2>

  { { $income := dict "salary" 2500000 "investments" 500000 }} { { $expenses :=
  dict "rent" 800000 "utilities" 200000 "food" 400000 }}

  <p>
    Ingresos Totales: { { add (get $income "salary") (get $income "investments")
    | currencyEntity }}
  </p>

  { { $totalExpenses := 0 }} { { range $key, $value := $expenses }} { {
  $totalExpenses = add $totalExpenses $value }} { { end }}

  <p>Gastos Totales: { { $totalExpenses | expenses }}</p>
  <p>
    Balance Neto: { { sub (add (get $income "salary") (get $income
    "investments")) $totalExpenses | currencyEntity }}
  </p>
</div>

Mejores Prácticas ​

  1. Verificar datos existentes: Utilizar condicionales para verificar si los datos existen antes de usarlos:

    { { if .Signatures }}
      <p>Documento firmado el { { (index .Signatures 0).CreatedAt | date_format "02/01/2006" }}</p>
    { { else }}
      <p>Documento pendiente de firma</p>
    { { end }}
  2. Aprovechar la biblioteca Sprig: Utilizar las funciones de Sprig para transformaciones de datos complejas:

    { { $data := dict "name" .Party.Profile.Natural.FirstName "amount" .Credit.Amount }}
    { { toJson $data }}
  3. Utilizar las funciones específicas del documento: Aprovechar las funciones específicas para obtener información contextual:

    <p>Este documento fue firmado el { { signedAt .Party.ID .Template.ID }}</p>
  4. Usar diccionarios para mapeos de valores:

    { { $tipoDocumentos := dict "CC" "Cédula de Ciudadanía" "CE" "Cédula de Extranjería" "TI" "Tarjeta de Identidad" }}
    { { get $tipoDocumentos .Credit.Debtor.Profile.Natural.IDType }}
  5. Utilizar plantillas anidadas para bloques reutilizables:

    Para secciones comunes que se repiten en varios documentos, considere utilizar plantillas anidadas.

Solución de Problemas ​

Errores Comunes ​

  1. Variable no encontrada: Si recibe un error indicando que una variable no existe, verifique que esté accediendo correctamente a la estructura de datos:

    error: can't evaluate field Title in type *domain.Credit

    Solución: Verificar que está accediendo al objeto correcto, por ejemplo .Document.Title en lugar de .Credit.Title.

  2. Función no reconocida: Si una función de plantilla no es reconocida, verifique que está utilizando una función disponible:

    function "formatCurrency" not defined

    Solución: Utilizar las funciones correctas como { { currency .Value }} en lugar de { { formatCurrency .Value }}.

  3. Error de sintaxis:

    unexpected "}" in operand

    Solución: Verificar que los delimitadores { { y }} estén balanceados y que la sintaxis sea correcta.

Depuración ​

Para depurar plantillas complejas, puede utilizar la función toJson de Sprig para ver la estructura completa de un objeto:

{ { toJson . }}

Esto mostrará todos los datos disponibles para la plantilla, lo que puede ser útil para identificar problemas.