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.