UNPKG

@ocelotlstudio/cfdi-pdf

Version:
583 lines 24.5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; exports.__esModule = true; exports.generatePdfContent = void 0; var catalogs_1 = require("../catalogs"); var toCurrency_1 = require("../utils/toCurrency"); var helper_1 = require("../utils/helper"); var check_1 = require("../utils/check"); var generateImpuestos = function (concepto) { var arr = []; if (concepto.traslados.length > 0) { arr.push('Traslados'); var content = concepto.traslados.map(function (traslado) { return [ catalogs_1.impuestosCatalog[traslado.impuesto] ? traslado.impuesto + " - " + catalogs_1.impuestosCatalog[traslado.impuesto] : '', traslado.tipoFactor == 'Exento' ? 'EXENTO' : "" + helper_1.formatCurrency(traslado.importe), ]; }); arr.push({ table: { body: content }, layout: 'noBorders' }); } if (concepto.retenciones.length > 0) { arr.push('Retenciones'); var content = concepto.retenciones.map(function (retencion) { return [ catalogs_1.impuestosCatalog[retencion.impuesto] ? retencion.impuesto + " - " + catalogs_1.impuestosCatalog[retencion.impuesto] : '', "" + helper_1.formatCurrency(retencion.importe), ]; }); arr.push({ table: { body: content }, layout: 'noBorders' }); } return arr; }; var generateConceptsTable = function (conceptos) { var arr = conceptos.map(function (concepto) { return [ concepto.clave, concepto.cantidad, concepto.claveUnidad, catalogs_1.clavesUnidadesCatalog[concepto.claveUnidad], concepto.descripcion, "" + helper_1.formatCurrency(concepto.valorUnitario), "" + helper_1.formatCurrency(concepto.descuento), { colSpan: 2, stack: generateImpuestos(concepto) }, '', "" + helper_1.formatCurrency(concepto.importe), ]; }); arr.unshift([ 'ClaveProdServ', 'Cant', 'Clave Unidad', 'Unidad', 'Descripción', 'Valor Unitario', 'Descuento', { colSpan: 2, text: 'Impuesto' }, '', 'Importe', ]); arr.unshift([ { text: 'PARTIDAS DEL COMPROBANTE', style: 'tableHeader', colSpan: 10, alignment: 'center' }, {}, {}, {}, {}, {}, {}, {}, {}, {}, ]); return arr; }; var generateRelatedDocs = function (docs) { var arr = docs.map(function (doc) { return [ doc.uuid, doc.metodoPago, doc.moneda, doc.tipoCambio, doc.numParcialidad, "" + helper_1.formatCurrency(doc.saldoAnterior), "" + helper_1.formatCurrency(doc.importePagado), "" + helper_1.formatCurrency(doc.saldoInsoluto), ]; }); arr.unshift([ 'UUID', 'Método de Pago', 'Moneda', 'Tipo de Cambio', 'Num. Parcialidad', 'Importe Saldo Anterior', 'Importe Pagado', 'Importe Saldo Insoluto', ]); arr.unshift([ { text: 'DOCUMENTOS RELACIONADOS', style: 'tableHeader', colSpan: 8, alignment: 'center' }, {}, {}, {}, {}, {}, {}, {}, ]); return arr; }; var generatePayments = function (pagos) { var arr = pagos.map(function (pago) { return [ { style: 'tableContent', table: { widths: [95, '*', 95, '*'], body: [ [ { text: 'INFORMACIÓN DE PAGO', style: 'tableHeader', colSpan: 4, alignment: 'center' }, {}, {}, {}, ], [ 'FECHA:', pago.fecha, 'FORMA PAGO:', catalogs_1.formasPagoCatalog[pago.formaPago] ? pago.formaPago + " - " + catalogs_1.formasPagoCatalog[pago.formaPago] : '', ], [ 'MONEDA:', catalogs_1.monedasCatalog[pago.moneda] ? pago.moneda + " - " + catalogs_1.monedasCatalog[pago.moneda] : '', 'MONTO:', "" + helper_1.formatCurrency(pago.monto), ], pago.tipoCambio ? ['TIPO DE CAMBIO:', pago.tipoCambio, '', ''] : ['', '', '', ''], ] }, layout: 'lightHorizontalLines' }, '\n', { style: 'tableList', table: { widths: ['*', 'auto', 'auto', 30, 20, 'auto', 'auto', 'auto'], body: generateRelatedDocs(pago.doctoRelacionados) }, layout: { fillColor: function (i) { return i % 2 !== 0 ? '#CCCCCC' : null; } } }, '\n', ]; }); return [].concat.apply([], arr); }; var generateQrCode = function (json) { var template = 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id={id}&re={re}&rr={rr}&tt={tt}&fe={fe}'; var qrCode = template .replace('{id}', json.timbreFiscalDigital.uuid) .replace('{re}', json.emisor.rfc) .replace('{rr}', json.receptor.rfc) .replace('{tt}', json.total) .replace('{fe}', json.timbreFiscalDigital.selloCFD.substring(json.timbreFiscalDigital.selloCFD.length - 8, json.timbreFiscalDigital.selloCFD.length)); return qrCode; }; var generateStampTable = function (json) { var arr = []; if (json.timbreFiscalDigital) { var fechaHoraCertificacion = json.timbreFiscalDigital.fechaTimbrado; arr.push([ { colSpan: 1, rowSpan: 8, qr: generateQrCode(json), fit: 140 }, '', '', ], ['', 'NUMERO SERIE CERTIFICADO SAT', check_1.exists(json.timbreFiscalDigital.noCertificadoSAT)], ['', 'NUMERO SERIE CERTIFICADO EMISOR', check_1.exists(json.noCertificado)], ['', 'FECHA HORA CERTIFICACION', fechaHoraCertificacion], ['', 'FOLIO FISCAL UUID', check_1.exists(json.timbreFiscalDigital.uuid)], ['', 'SELLO DIGITAL', helper_1.breakEveryNCharacters(check_1.exists(json.timbreFiscalDigital.selloCFD), 86)], ['', 'SELLO DEL SAT', helper_1.breakEveryNCharacters(check_1.exists(json.timbreFiscalDigital.selloSAT), 86)]); } arr.push(['', 'CADENA ORIGINAL CC:', { text: helper_1.breakEveryNCharacters(json.cadenaOriginalCC, 86) }]); return arr; }; var generateAddress = function (receptor, address) { var arr = []; var addressArray = []; if (address) { addressArray.push('DOMICILIO:', address); } addressArray.push('USO CFDI:', { colSpan: address ? 1 : 3, text: catalogs_1.usosCfdiCatalog[receptor.usoCFDI] ? receptor.usoCFDI + " - " + catalogs_1.usosCfdiCatalog[receptor.usoCFDI] : '' }); arr.push(addressArray); if (receptor.residenciaFiscal && receptor.numRegIdTrib) { arr.push([ 'RESIDENCIA FISCAL:', check_1.exists(receptor.residenciaFiscal), 'NUMERO ID TRIB.:', check_1.exists(receptor.numRegIdTrib), ]); } return arr; }; // generate content array used in PDFMake var generateContent = function (json, logo, text, address) { return __awaiter(void 0, void 0, void 0, function () { var content, header, _a, _b, _c, _d; var _e, _f, _g; return __generator(this, function (_h) { switch (_h.label) { case 0: content = []; header = { alignment: 'center', style: 'tableContent', table: { widths: ['auto', 'auto', 'auto'], fontSize: 9, body: [ ['', 'SERIE:', json.serie], ['', 'FOLIO:', json.folio], ['', 'FECHA:', json.fecha], ['', 'EXPEDICION:', json.lugar], [ '', 'COMPROBANTE:', catalogs_1.tiposComprobantesCatalog[json.tipoDeComprobante] ? json.tipoDeComprobante + " - " + catalogs_1.tiposComprobantesCatalog[json.tipoDeComprobante] : '', ], ] }, layout: 'lightHorizontalLines' }; if (logo) { header.table.body[0][0] = { rowSpan: 5, image: logo, fit: [260, 260] }; header.table.widths = ['*', 'auto', 'auto']; } content.push(header); // space content.push('\n'); // this block contains info. about "emisor" object content.push({ style: 'tableContent', table: { widths: ['auto', '*', 'auto', 'auto'], body: [ [ { text: 'EMISOR', style: 'tableHeader', colSpan: 4, alignment: 'center' }, {}, {}, {}, ], ['NOMBRE:', check_1.exists(json.emisor.nombre), 'RFC:', check_1.exists(json.emisor.rfc)], [ 'REGIMEN FISCAL:', { colSpan: 3, text: catalogs_1.regimenesFiscalesCatalog[json.emisor.regimenFiscal] ? json.emisor.regimenFiscal + " - " + catalogs_1.regimenesFiscalesCatalog[json.emisor.regimenFiscal] : '' }, '', ], ] }, layout: 'lightHorizontalLines' }); // space content.push('\n'); // this block contains info. about "receptor" object content.push({ style: 'tableContent', table: { widths: ['auto', '*', 'auto', 'auto'], body: __spreadArray([ [ { text: 'RECEPTOR', style: 'tableHeader', colSpan: 4, alignment: 'center' }, {}, {}, {}, ], ['NOMBRE:', check_1.exists(json.receptor.nombre), 'RFC:', check_1.exists(json.receptor.rfc)] ], generateAddress(json.receptor, address)) }, layout: 'lightHorizontalLines' }); // space content.push('\n'); // check type of invoice if (json.tipoDeComprobante.toUpperCase() === 'I' || json.tipoDeComprobante.toUpperCase() === 'E') { // this block contains general info. about the invoice content.push({ style: 'tableContent', table: { widths: [95, '*', 95, '*'], body: [ [ { text: 'DATOS GENERALES DEL COMPROBANTE', style: 'tableHeader', colSpan: 4, alignment: 'center' }, {}, {}, {}, ], [ 'MONEDA:', catalogs_1.monedasCatalog[json.moneda] ? json.moneda + " - " + catalogs_1.monedasCatalog[json.moneda] : '', 'FORMA PAGO:', catalogs_1.formasPagoCatalog[json.formaPago] ? json.formaPago + " - " + catalogs_1.formasPagoCatalog[json.formaPago] : '', ], ['TIPO DE CAMBIO:', json.tipoCambio, 'CONDICIONES DE PAGO:', json.condicionesDePago], [ 'CLAVE CONFIRMACION:', json.confirmacion, 'METODO DE PAGO:', catalogs_1.metodosPagoCatalog[json.metodoPago] ? json.metodoPago + " - " + catalogs_1.metodosPagoCatalog[json.metodoPago] : '', ], ] }, layout: 'lightHorizontalLines' }); // space content.push('\n'); } // this block contains the concepts of the invoice content.push({ style: 'tableList', table: { widths: ['auto', 'auto', 'auto', 'auto', '*', 'auto', 'auto', 'auto', 'auto', 'auto'], body: generateConceptsTable(json.conceptos) }, layout: { fillColor: function (i) { return i % 2 !== 0 ? '#CCCCCC' : null; } } }); // space content.push('\n'); if (!(json.tipoDeComprobante.toUpperCase() === 'I' || json.tipoDeComprobante.toUpperCase() === 'E')) return [3 /*break*/, 2]; // this block contains currency related info. _b = (_a = content).push; _e = { style: 'tableContent' }; _f = { widths: ['auto', '*', 'auto', '*'] }; _c = [[ { text: 'CFDI RELACIONADO', style: 'tableHeader', colSpan: 4, alignment: 'center' }, {}, {}, {}, ], [ 'TIPO RELACION:', catalogs_1.tiposRelacionesCatalog[json.cfdiRelacionado ? json.cfdiRelacionado.tipoRelacion : ''] ? json.cfdiRelacionado.tipoRelacion + " - " + catalogs_1.tiposRelacionesCatalog[json.cfdiRelacionado.tipoRelacion] : '', 'CFDI RELACIONADO:', json.cfdiRelacionado ? check_1.exists(json.cfdiRelacionado.uuid) : '', ], ['SUBTOTAL:', "" + helper_1.formatCurrency(json.subTotal), 'TOTAL:', "" + helper_1.formatCurrency(json.total)]]; _d = ['DESCUENTO:', "" + helper_1.formatCurrency(json.descuento), { text: 'IMPORTE CON LETRA:' }]; _g = {}; return [4 /*yield*/, toCurrency_1.toCurrency(parseFloat(json.total), json.moneda)]; case 1: // this block contains currency related info. _b.apply(_a, [(_e.table = (_f.body = _c.concat([ _d.concat([ (_g.text = _h.sent(), _g) ]), [ 'TOTAL IMP. TRASLADADOS:', "" + helper_1.formatCurrency(check_1.existsValue(json.totalImpuestosTrasladados)), 'TOTAL IMP. RETENIDOS:', "" + helper_1.formatCurrency(check_1.existsValue(json.totalImpuestosRetenidos)), ] ]), _f), _e.layout = 'lightHorizontalLines', _e)]); // space content.push('\n'); _h.label = 2; case 2: // check type of invoice if (json.tipoDeComprobante.toUpperCase() === 'P') { // this block contains info. about payment content = content.concat(generatePayments(json.pagos)); } if (text) { // observations content.push({ style: 'tableContent', table: { widths: ['*'], body: [[{ text: 'OBSERVACIONES', style: 'tableHeader' }], [text]] }, layout: 'lightHorizontalLines' }); // space content.push('\n'); } // this block contains info. about the stamp content.push({ style: 'tableSat', table: { widths: ['auto', 'auto', '*'], body: generateStampTable(json) }, layout: 'lightHorizontalLines' }); return [2 /*return*/, content]; } }); }); }; /** * Receives a json and returns a pdf content object for pdfmake * @param {Cfdi} json result json from using parseData function */ var generatePdfContent = function (json, options) { return __awaiter(void 0, void 0, void 0, function () { var logo, dd; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: logo = options.image; if (options.cadenaOriginal) json.cadenaOriginalCC = options.cadenaOriginal; _a = {}; return [4 /*yield*/, generateContent(json, logo, options.text, options.address)]; case 1: dd = (_a.content = _b.sent(), _a.styles = { tableHeader: { bold: true, fontSize: 10, color: 'black' }, tableContent: { fontSize: 8, color: 'black', alignment: 'left' }, tableList: { fontSize: 7, color: 'black', alignment: 'center' }, tableSat: { fontSize: 5, color: 'black', alignment: 'left' } }, _a.defaultStyle = { // alignment: 'justify' }, _a.footer = function () { return { style: 'tableContent', table: { widths: ['auto', '*', 'auto', 'auto'], body: [ [ { text: 'Este documento es una representación impresa de un CFDI', style: 'tableList', colSpan: 4, alignment: 'center' }, {}, {}, {}, ], ] }, layout: 'lightHorizontalLines' }; }, _a); return [2 /*return*/, dd]; } }); }); }; exports.generatePdfContent = generatePdfContent; //# sourceMappingURL=generateContent.js.map