UNPKG

sic-builder

Version:
379 lines (326 loc) 17.8 kB
/* ---------------------------------------------------------------------------/ 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 }