Appearance
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 documentoDatos 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éditoFunciones 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 campoBiblioteca 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ónPara 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 personalizadoFunciones 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ónDetalles 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 documentoTemplateID: 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 personalizadosfield_name: Nombre del campo personalizado a obtenerdefault_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
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 }}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 }}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>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 }}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
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.CreditSolución: Verificar que está accediendo al objeto correcto, por ejemplo
.Document.Titleen lugar de.Credit.Title.Función no reconocida: Si una función de plantilla no es reconocida, verifique que está utilizando una función disponible:
function "formatCurrency" not definedSolución: Utilizar las funciones correctas como
{ { currency .Value }}en lugar de{ { formatCurrency .Value }}.Error de sintaxis:
unexpected "}" in operandSolució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.