sic-builder
Version:
Construye SIC
379 lines (326 loc) • 17.8 kB
JavaScript
/* ---------------------------------------------------------------------------/
Copyright (C) ANANASOFT SOCIEDAD ANONIMA - All Rights Reserved
Unauthorized copying of this file, via any medium is strictly prohibited
Proprietary and confidential
Written by @Luis Matamoros P <luis.matamoros@ananasoft.com>, April 2022
/--------------------------------------------------------------------------- */
// ----------------------------------------------------------------//
// Crea SIC //
// @Anana Soft //
// Author: Luis Matamoros P //
// //
// ----------------------------------------------------------------//
/* -----------------------------------------------------------------/
Date: 12-05-2022
Author: Luis Matamoros P
Changes:
First version
/----------------------------------------------------------------- */
const PDFDocument = require("pdfkit-table"),
axios = require("axios"),
sizeOf = require("image-size"),
signatureDefault = "iVBORw0KGgoAAAANSUhEUgAAAnYAAAC0CAIAAACWifY4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAK7SURBVHhe7dUxAQAADMOg+TfdqcgHJrgBAAHFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwAJBQLAAnFAkBCsQCQUCwABLYHyk0Erf2VY+oAAAAASUVORK5CYII=",
sharp = require("sharp"),
fontSize_ = 8,
path = require("path")
async function fetchImage(src) {
const image = await axios
.get(src, {
responseType: "arraybuffer"
})
return image.data
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight)
return { width: srcWidth * ratio, height: srcHeight * ratio }
}
async function cropSignature (signature) {
var imgSignature
try {
var signature_ = signature.startsWith("data:image/png;base64,") ? signature.substr(22) : signature
imgSignature = Buffer.from(signature_, "base64")
var dimensions = sizeOf(imgSignature)
if (dimensions.height > 260) {
imgSignature = await sharp(imgSignature)
.extract({ left: 0, top: 0, width: dimensions.width, height: 260 })
.png()
.toBuffer()
}
} catch (err) {
imgSignature = Buffer.from(signatureDefault, "base64")
}
return imgSignature
}
function addHeaderInfo (doc, logo, margin_) {
// IMAGEN ENTIDAD
doc.image(logo, ((doc.page.width - 350) / 2), 15, {width: 350, height: 50})
// TEXTO CABECERA
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-BoldItalic.ttf"))
.fontSize(fontSize_)
.text("R-10-P-ST-147 Versión 3.0", 0, 75, {continued: false, align: "center"})
// DIBUJA RECTANGULO
doc.lineJoin("miter")
.rect(margin_, 90, doc.page.width - 80, 40)
.stroke()
doc.lineJoin("miter")
.rect(margin_ + 2, 92, doc.page.width - 84, 36)
.stroke()
// TEXTO DENTRO DEL RECTANGULO
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Bold.ttf"))
.fontSize(fontSize_)
.text("AUTORIZACIÓN DE LA PERSONA FÍSICA PARA", 0, 93, {continued: false, align: "center"})
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Bold.ttf"))
.fontSize(fontSize_)
.text("ENTREGAR INFORMACION CREDITICIA A UNA ENTIDAD", 0, 111, {continued: false, align: "center"})
}
function addPersonBankInfo (doc, date, nameClient, documentId, nameBank, bankId) {
// TABLA INFORMACION PERSONA - BANCO
var h = 135
var th = 16
doc.lineJoin("miter")
.rect(40, h, doc.page.width - 280, th)
.fill("#ddd")
doc.lineJoin("miter")
.rect((40 + doc.page.width - 280 + 2), h, doc.page.width - 80 - (doc.page.width - 280), th)
.fill("#ddd")
doc.lineJoin("miter")
.rect(40, h + th, doc.page.width - 280, 18)
.fill("#fff")
doc.lineJoin("miter")
.rect((40 + doc.page.width - 280 + 2), h + th, doc.page.width - 80 - (doc.page.width - 280), 18)
.fill("#fff")
doc.lineJoin("miter")
.rect(40, h + th * 2, doc.page.width - 280, 18)
.fill("#ddd")
doc.lineJoin("miter")
.rect((40 + doc.page.width - 280 + 2), h + th * 2, doc.page.width - 80 - (doc.page.width - 280), 18)
.fill("#ddd")
doc.lineJoin("miter")
.rect(40, h + th * 3, doc.page.width - 280, 18)
.fill("#fff")
doc.lineJoin("miter")
.rect((40 + doc.page.width - 280 + 2), h + th * 3, doc.page.width - 80 - (doc.page.width - 280), 18)
.fill("#fff")
doc.lineJoin("miter")
.rect(40, h + th * 4, doc.page.width - 280, 18)
.fill("#ddd")
doc.lineJoin("miter")
.rect((40 + doc.page.width - 280 + 2), h + th * 4, doc.page.width - 80 - (doc.page.width - 280), 18)
.fill("#ddd")
doc.lineJoin("miter")
.rect(40, h + th * 5, doc.page.width - 280, 18)
.fill("#fff")
doc.lineJoin("miter")
.rect((40 + doc.page.width - 280 + 2), h + th * 5, doc.page.width - 80 - (doc.page.width - 280), 18)
.fill("#fff")
// TEXTO DENTRO TABLA INFORMACION PERSONA - BANCO
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Fecha(formato dd/mm/aaaa):", 45, h)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text(`${("" + date.getDate()).padStart(2, "0")}/${("" + (date.getMonth() + 1)).padStart(2, "0")}/${date.getFullYear()}`, (40 + doc.page.width - 280 + 7), h)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Hora (formato hh:mm):", 45, h + th * 1)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text(`${("" + date.getHours()).padStart(2, "0")}:${("" + date.getMinutes()).padStart(2, "0")}`, (40 + doc.page.width - 280 + 7), h + th * 1)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Nombre del usuario autorizado (Nombre y apellidos):", 45, h + th * 2)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text(nameClient, (40 + doc.page.width - 280 + 7), h + th * 2)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Identificación del usuario autorizado (documento de identidad):", 45, h + th * 3)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text(documentId, (40 + doc.page.width - 280 + 7), h + th * 3)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Nombre de la entidad que tramita (Nombre entidad):", 45, h + th * 4)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text(nameBank, (40 + doc.page.width - 280 + 7), h + th * 4)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Identificación de la entidad que tramita (Cédula jurídica de la entidad):", 45, h + th * 5)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text(`# ${bankId}`, (40 + doc.page.width - 280 + 7), h + th * 5)
}
function addConsentText (doc, nameClient, documentId) {
// TEXTO CONSENTIMIENTO
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Yo, ", 40, 235, {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-BoldItalic.ttf"))
.text(`${nameClient}`, {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.text(" identificación número ", {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-BoldItalic.ttf"))
.text(`${documentId} `, {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.text(" autorizo a la Superintendencia General de Entidades Financieras para que proporcione", {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-BoldItalic.ttf"))
.text(", durante el periodo en que mantenga relación crediticia con la entidad, ", {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.text("la información crediticia que sobre mi persona se encuentre registrada en la SUGEF, de conformidad con los artículos 133 de la Ley Orgánica del Banco Central de Costa Rica, Ley Nº 7558, así como la información relacionada con los Grupos de Interés Económico, de conformidad con el Artículo 135 de la misma Ley, a las partes involucradas.", {continued: false, align: "justify"})
// TEXTO INFORMATIVO IDENTIFICACIONES
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("Asimismo, con el fin de facilitar mi identificación en el sistema financiero, declaro que en el pasado también he utilizado en Costa Rica las siguientes identificaciones:", 40, 300, {continued: false, align: "justify"})
}
function addTables (doc) {
// TABLA IDENTIFICACIONES
doc.moveDown()
const table = {
headers: [
{ label:"Nombre y apellidos", headerAlign: "center", options: { fontSize: 12 } },
{ label:"No. identificación", headerAlign: "center", options: { fontSize: 12 } },
{ label:"Documento(*)", headerAlign: "center", options: { fontSize: 12 } }
],
rows: [
[" ", " ", " "]
]
}
doc.table(table, {
x: ((doc.page.width - 450) / 2),
columnsSize: [ 250, 100, 100 ],
divider: {
header: { disabled: false, width: 2, opacity: 1 },
horizontal: { disabled: false, width: 0.5, opacity: 0.5 }
}
})
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.fillColor("black")
.text("(*) Según los siguientes códigos:", ((doc.page.width - 400) / 2), 380)
doc.moveDown()
// TABLA DE CODIGOS
const table2 = {
y: 665,
minRowHeight: 10,
headers: [
{ label:"Código", headerAlign: "center", options: { fontSize: 10 } },
{ label:"Documento de identificación", headerAlign: "center", options: { fontSize: 10 } }
],
rows: [
["CIC", "Cédula de identidad costarricense (TIM en caso de menores de edad)"],
["IEX", "Documento de radicados en el país (identificador único para extranjeros que será emitido por Migración a partir de setiembre 2005)."],
["CRP", "Cédula de residencia permanente"],
["CRR", "Carné de residente rentista"],
["RE", "Cédula de residencia permanente libre de condición (Régimen de Excepción)"],
["APO", "Documento de residencia de asilado político"],
["CRT", "Carné de residencia temporal"],
["CRE", "Carné de refugiado"],
["PEX", "Pasaporte extranjero"]
]
}
doc.table(table2, {
x: ((doc.page.width - 450) / 2),
columnsSize: [ 50, 400 ],
divider: {
header: { disabled: false, width: 2, opacity: 1 },
horizontal: { disabled: false, width: 0.5, opacity: 0.5 }
}
})
}
function addSignature (doc, imgSignature) {
// IMAGEN FIRMA
var nextText = 0, mW = 350, mH = 50
try {
const dimensions = sizeOf(imgSignature)
const aspect = calculateAspectRatioFit(dimensions.width, dimensions.height, mW, mH)
doc.image(imgSignature, ((doc.page.width - aspect.width) / 2), 580, {
width: aspect.width, height: aspect.height
})
nextText = (580 + aspect.height + 5)
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Bold.ttf"))
.fontSize(8)
.text("Firma de la persona que autoriza", 40, nextText, {continued: false, align: "center"})
} catch (err) {
console.log(err)
doc.image(Buffer.from(signatureDefault, "base64"), ((doc.page.width - mW) / 2), 580, {
width: mW, height: mH
})
nextText = 645
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Bold.ttf"))
.fontSize(8)
.text("Firma de la persona que autoriza", 40, nextText, {continued: false, align: "center"})
}
return nextText
}
function addNote (doc, nameClient, nextText) {
// TEXTO INFORMATIVO
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Bold.ttf"))
.fontSize(8)
.fillColor("black")
.text("Nota: ", 40, (nextText + 20), {continued: true, align: "justify"})
.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.text("Se informa que de conformidad con los derechos que le asisten, esta autorización puede ser revocada en el momento y por las razones que estime pertinentes. No obstante lo anterior, se advierte que la revocatoria de esta autorización, de existir cláusulas punitivas en los contratos de crédito vigentes, podría provocar su aplicación de conformidad con los términos que se hayan pactado en el contrato suscrito entre las partes.", {continued: false, align: "justify"})
// NOMBRE PERSONA
doc.font(path.resolve(process.cwd(), "modules/services/fonts/OpenSans-Regular.ttf"))
.fontSize(8)
.text(`c. ${nameClient}`, 40, (nextText + 70), {continued: false})
}
function buildPDF (documentId, nameClient, bankId, nameBank, bankLogo, signature) {
return new Promise (async (resolve) => {
// CREA DOCUMENTO
var margin_ = 40
var doc = new PDFDocument({autoFirstPage: false, margin: margin_, size: [612, 792]})
var buffers = []
doc.on("data", buffers.push.bind(buffers))
// OBTIENE IMAGEN DE LA ENTIDAD
const logo = await fetchImage(bankLogo)
// RECORTA ALTURA DE LA FIRMA
var imgSignature = await cropSignature(signature)
doc.on("pageAdded", async () => {
const date = new Date()
// AGREGA LOS DATOS INICIALES DEL DOCUMENTO
addHeaderInfo (doc, logo, margin_)
// DATOS DE LA PERSONA Y EL BANCO
addPersonBankInfo(doc, date, nameClient, documentId, nameBank, bankId)
// TEXTO CONSENTIMIENTO
addConsentText(doc, nameClient, documentId)
// AGREGA LAS TABLAS
addTables(doc)
// AGREGA FIRMA
var nextText = addSignature(doc, imgSignature)
// AGREGA NOTA FINAL
addNote(doc, nameClient, nextText)
})
doc.addPage()
doc.end()
doc.on("end", () => {
const sicData = Buffer.concat(buffers).toString("base64")
resolve({
status: 200,
data: {
name: `sic${nameClient}.pdf`.replace(" ", "_"),
content: sicData
}
})
})
})
}
module.exports = async (documentId, nameClient, bankId, nameBank, bankLogo, signature) => {
const response = await buildPDF(documentId, nameClient, bankId, nameBank, bankLogo, signature)
return response
}