UNPKG

fecr

Version:

Modulo de comprobantes electrónicos para el API del Ministerio de Hacienda de Costa Rica versión 4.3

284 lines (240 loc) 7.82 kB
"use strict"; var xml2js = require("xml2js"); var moment = require("moment-timezone"); var utils = require("./utils.js"); var signer = require("./signer.js"); var Summary = require("./voucher/summary.js"); class Voucher { constructor(voucher) { this.cert = voucher.cert; this.api = voucher.api; this.date = voucher.date ? moment.tz(voucher.date, "America/Costa_Rica") : moment.tz("America/Costa_Rica"); this.issuer = voucher.issuer; this.headquarters = voucher.headquarters ? voucher.headquarters : 1; this.terminal = voucher.terminal ? voucher.terminal : 1; this.number = voucher.number; this.situation = voucher.situation ? voucher.situation : "1"; this.activityCode = voucher.activityCode; this.securityCode = voucher.securityCode; if (voucher.receiver) { this.receiver = voucher.receiver; } this.condition = voucher.condition ? voucher.condition : "01"; this.paymentType = voucher.paymentType ? voucher.paymentType : "01"; if (voucher.creditTerm) { this.creditTerm = voucher.creditTerm; } if (voucher.items) { this.items = voucher.items; } if (voucher.otherCharges) { this.otherCharges = voucher.otherCharges; } if (voucher.currency) { this.currency = voucher.currency; } if (voucher.exchangeRate) { this.exchangeRate = voucher.exchangeRate; } if (voucher.summary) { this.summary = voucher.summary; } else { this.generateSummary(); } if (voucher.references) { this.references = voucher.references; } if (voucher.others) { this.others = voucher.others; } if (voucher.callbackUrl) { this.callbackUrl = voucher.callbackUrl; } } buildXml() { var voucher = { [this.rootTag]: { $: this.namespaces } }; voucher[this.rootTag].Clave = this.key; voucher[this.rootTag].CodigoActividad = this.activityCode; voucher[this.rootTag].NumeroConsecutivo = this.sequence; voucher[this.rootTag].FechaEmision = this.date.format(); voucher[this.rootTag].Emisor = this.issuer.generate(); if (this.receiver) { voucher[this.rootTag].Receptor = this.receiver.generate(); } voucher[this.rootTag].CondicionVenta = this.condition; if (this.creditTerm && this.condition === "02") { voucher[this.rootTag].PlazoCredito = this.creditTerm; } voucher[this.rootTag].MedioPago = this.paymentType; if (this.items) { var lines = []; this.items.forEach(item => { lines.push(item.generate()); }); voucher[this.rootTag].DetalleServicio = { LineaDetalle: lines }; } if (this.otherCharges) { var charges = []; this.otherCharges.forEach(charge => { charges.push(charge.generate()); }); voucher[this.rootTag].OtrosCargos = charges; } voucher[this.rootTag].ResumenFactura = this.summary ? this.summary.generate() : this.generateSummary({ items: voucher[this.rootTag].DetalleServicio.LineaDetalle, otherCharges: voucher[this.rootTag].OtrosCargos }); if (this.references) { var references = []; this.references.forEach(reference => { references.push(reference.generate()); }); voucher[this.rootTag].InformacionReferencia = references; } if (this.others) { voucher[this.rootTag].Otros = this.others.generate(); } var builder = new xml2js.Builder(); var xmlString = builder.buildObject(voucher); this.data = voucher; return xmlString.replace(/[\r\n]/g, "").replace(/\s{2,}/g, ""); } generateSequence() { var headquarters = utils.zfill(this.headquarters, 3); var terminal = utils.zfill(this.terminal, 5); var type = utils.zfill(this.voucherType, 2); var number = utils.zfill(this.number, 10); this.sequence = headquarters + terminal + type + number; } generateKey() { var country = "506"; var day = utils.zfill(this.date.date(), 2); var month = utils.zfill(this.date.month() + 1, 2); var year = utils.zfill(this.date.year() - 2000, 2); var idNumber = utils.zfill(this.issuer.id, 12); var type = utils.zfill(this.situation, 1); var securityCode = utils.zfill(this.securityCode, 8); // eslint-disable-next-line max-len this.key = country + day + month + year + idNumber + this.sequence + type + securityCode; } generateSummary() { var servicesTaxableTotal = 0; var servicesExentTotal = 0; var servicesExoneTotal = 0; var goodsTaxableTotal = 0; var goodsExentTotal = 0; var goodsExoneTotal = 0; var discountTotal = 0; var taxTotal = 0; var otherChargesTotal = 0; this.otherCharges.forEach((_ref) => { var { amount } = _ref; otherChargesTotal += Number(amount); }); this.items.forEach(item => { if (item.taxes) { var allowances = []; item.taxes.forEach((_ref2) => { var { allowance } = _ref2; if (allowance) allowances.push(allowance); }); if (item.unit === "Al" || item.unit === "Alc" || item.unit === "Cm" || item.unit === "I" || item.unit === "Os" || item.unit === "Sp" || item.unit === "Spe" || item.unit === "St") { if (allowances.length > 0) { servicesExoneTotal += item.total; } else { servicesTaxableTotal += item.total; } } else { if (allowances.length > 0) { goodsExoneTotal += item.total; } else { goodsTaxableTotal += item.total; } } taxTotal += item.taxNet; } else if (item.unit === "Al" || item.unit === "Alc" || item.unit === "Cm" || item.unit === "I" || item.unit === "Os" || item.unit === "Sp" || item.unit === "Spe" || item.unit === "St") { servicesExentTotal += item.total; } else { goodsExentTotal += item.total; } if (item.discounts) { item.discounts.forEach((_ref3) => { var { discountAmount } = _ref3; discountTotal += discountAmount; }); } }); this.summary = new Summary({ currency: this.currency, exchangeRate: this.exchangeRate, servicesTaxableTotal, servicesExentTotal, servicesExoneTotal, goodsTaxableTotal, goodsExentTotal, goodsExoneTotal, discountTotal, taxTotal, otherChargesTotal }); } sign() { return new Promise((resolve, reject) => { signer.signXmlString(this.buildXml(), this.cert).then(signedXml => { this.signedXml = signedXml; this.signedXmlBase64 = Buffer.from(signedXml).toString("base64"); resolve(signedXml); }).catch(error => { reject(error); }); }); } getPayload() { if (!this.signedXmlBase64) { throw Error("the document has not been signed yet"); } var payload = { clave: this.key, fecha: this.date.format(), emisor: { tipoIdentificacion: this.issuer.idType, numeroIdentificacion: this.issuer.id } }; if (this.receiver) { payload.receptor = { tipoIdentificacion: this.receiver.idType, numeroIdentificacion: this.receiver.id }; } if (this.callbackUrl) { payload.callbackUrl = this.callbackUrl; } payload.comprobanteXml = this.signedXmlBase64; return payload; } send() { return new Promise((resolve, reject) => { this.sign().then(() => this.api.send(this.getPayload())).then(() => { resolve({ data: this.data, xml: this.signedXmlBase64 }); }).catch(error => { reject(error); }); }); } } module.exports = Voucher;