UNPKG

@facturacr/atv-sdk

Version:

Librería (SDK) de Javascript/NodeJS para acceder al API de Administración Tributaria Virtual (ATV) del Ministerio de Hacienda.

155 lines 9.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mapReceptorMessageToAtvFormat = exports.mapDocumentToAtvFormat = void 0; const parseAtvMoneyFormat = (amount) => { return parseFloat(amount.toFixed(5)); }; const isPurchaseInvoice = (docName) => docName === 'FacturaElectronicaCompra'; const mapOrderLinesToAtvFormat = (orderLines, docName) => { const LineaDetalle = orderLines.map((orderLine) => { var _a; const impuestoMonto = orderLine.tax ? parseAtvMoneyFormat((_a = orderLine.tax.amount) !== null && _a !== void 0 ? _a : 0) : 0; return Object.assign(Object.assign(Object.assign({ NumeroLinea: orderLine.lineNumber, CodigoCABYS: orderLine.code, // CodigoComercial Cantidad: orderLine.quantity, UnidadMedida: orderLine.measureUnit, // UnidadMedidaComercial Detalle: orderLine.detail, PrecioUnitario: orderLine.unitaryPrice, MontoTotal: orderLine.totalAmount, // Descuento SubTotal: orderLine.subTotal, BaseImponible: orderLine.subTotal }, (orderLine.tax && { Impuesto: { Codigo: orderLine.tax.code, CodigoTarifaIVA: orderLine.tax.rateCode, Tarifa: orderLine.tax.rate, Monto: impuestoMonto // Exoneracion is explicitly excluded here } })), (!isPurchaseInvoice(docName) && { ImpuestoAsumidoEmisorFabrica: 0 })), { // @ts-expect-error pending-to-fix ImpuestoNeto: parseAtvMoneyFormat(orderLine.tax.amount), MontoTotalLinea: parseAtvMoneyFormat(orderLine.totalOrderLineAmount), exchangeRate: orderLine.exchangeRate, currency: orderLine.currency }); }); return { LineaDetalle }; }; const mapSummaryInvoice = (document, docName) => { const summaryInvoice = document.summaryInvoice; const orderLines = document.orderLines; // Still need access to order lines for breakdown // --- Lógica para TotalDesgloseImpuesto (sin considerar exoneraciones) --- const taxBreakdownMap = new Map(); orderLines.forEach(orderLine => { var _a; if (((_a = orderLine.tax) === null || _a === void 0 ? void 0 : _a.amount) !== undefined && orderLine.tax.amount !== null && orderLine.tax.amount > 0) { const key = `${orderLine.tax.code}-${orderLine.tax.rateCode}`; const currentTotal = taxBreakdownMap.get(key) || 0; taxBreakdownMap.set(key, currentTotal + orderLine.tax.amount); } }); const TotalDesgloseImpuesto = Array.from(taxBreakdownMap.entries()).map(([key, totalMonto]) => { const [Codigo, CodigoTarifaIVA, Tarifa] = key.split('-'); return { Codigo, CodigoTarifaIVA, Tarifa, TotalMontoImpuesto: parseAtvMoneyFormat(totalMonto) }; }); return Object.assign(Object.assign({ CodigoTipoMoneda: { // @ts-expect-error pending-to-fix CodigoMoneda: summaryInvoice.currency.code, // @ts-expect-error pending-to-fix TipoCambio: summaryInvoice.currency.exchangeRate }, TotalServGravados: parseAtvMoneyFormat(summaryInvoice.totalEncumberedServices), TotalServExentos: parseAtvMoneyFormat(summaryInvoice.totalExemptServices), TotalServNoSujeto: parseAtvMoneyFormat(summaryInvoice.totalNonTaxableServices), // @ts-expect-error pending-to-fix TotalMercanciasGravadas: parseAtvMoneyFormat(summaryInvoice.totalEncumberedMerchandise), // @ts-expect-error pending-to-fix TotalMercanciasExentas: parseAtvMoneyFormat(summaryInvoice.totalExemptMerchandise), TotalMercNoSujeta: parseAtvMoneyFormat(summaryInvoice.totalNonTaxableMerchandise), TotalGravado: parseAtvMoneyFormat(summaryInvoice.totalEncumbered), TotalExento: parseAtvMoneyFormat(summaryInvoice.totalExempt), TotalExonerado: parseAtvMoneyFormat(summaryInvoice.totalExonerated), TotalNoSujeto: parseAtvMoneyFormat(summaryInvoice.totalNonTaxable), TotalVenta: parseAtvMoneyFormat(summaryInvoice.totalSale), // @ts-expect-error pending-to-fix TotalDescuentos: parseAtvMoneyFormat(summaryInvoice.totalDiscounts), // @ts-expect-error pending-to-fix TotalVentaNeta: parseAtvMoneyFormat(summaryInvoice.totalNetSale), TotalDesgloseImpuesto, TotalImpuesto: parseAtvMoneyFormat(summaryInvoice.totalTaxes) }, (!isPurchaseInvoice(docName) && { TotalImpAsumEmisorFabrica: 0 })), { TotalOtrosCargos: 0, MedioPago: { // @ts-expect-error pending-to-fix TipoMedioPago: document.paymentMethod }, TotalComprobante: parseAtvMoneyFormat(summaryInvoice.totalVoucher) }); }; const mapPerson = (person) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; const atvPerson = { Nombre: person.fullName, Identificacion: { Tipo: person.identifierType, Numero: person.identifierId }, NombreComercial: person.commercialName }; if (((_a = person.location) === null || _a === void 0 ? void 0 : _a.province) && ((_b = person.location) === null || _b === void 0 ? void 0 : _b.canton) && ((_c = person.location) === null || _c === void 0 ? void 0 : _c.district)) { atvPerson.Ubicacion = { Provincia: (_d = person.location) === null || _d === void 0 ? void 0 : _d.province, Canton: (_f = (_e = person.location) === null || _e === void 0 ? void 0 : _e.canton) === null || _f === void 0 ? void 0 : _f.padStart(2, '0'), Distrito: (_h = (_g = person.location) === null || _g === void 0 ? void 0 : _g.district) === null || _h === void 0 ? void 0 : _h.padStart(2, '0'), Barrio: (_k = (_j = person.location) === null || _j === void 0 ? void 0 : _j.neighborhood) === null || _k === void 0 ? void 0 : _k.padStart(5, '0'), OtrasSenas: (_l = person.location) === null || _l === void 0 ? void 0 : _l.details }; } if (person.foreignAddress) { atvPerson.OtrasSenasExtranjero = person.foreignAddress; } if (((_m = person.phone) === null || _m === void 0 ? void 0 : _m.countryCode) && ((_o = person.phone) === null || _o === void 0 ? void 0 : _o.number)) { atvPerson.Telefono = { CodigoPais: (_p = person.phone) === null || _p === void 0 ? void 0 : _p.countryCode, NumTelefono: (_q = person.phone) === null || _q === void 0 ? void 0 : _q.number }; } if (person.email) { atvPerson.CorreoElectronico = person.email; } return atvPerson; }; const mapReferenceInformation = (referenceInfo) => { return { TipoDocIR: referenceInfo.docType, Numero: referenceInfo.refNumber, FechaEmisionIR: referenceInfo.issueDate.toISOString(), Codigo: referenceInfo.code, Razon: referenceInfo.reason }; }; const mapDocumentToAtvFormat = (docName, document) => { var _a, _b; const key = docName; const activitySource = isPurchaseInvoice(docName) && document.receiver ? document.receiver : document.emitter; const doc = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ Clave: document.clave, ProveedorSistemas: document.providerId, CodigoActividadEmisor: activitySource.activityCode.padStart(6, '0') }, (document.receiver && { CodigoActividadReceptor: (_b = (_a = document.receiver) === null || _a === void 0 ? void 0 : _a.activityCode) === null || _b === void 0 ? void 0 : _b.padStart(6, '0') })), { NumeroConsecutivo: document.fullConsecutive, FechaEmision: document.issueDate.toISOString(), Emisor: mapPerson(document.emitter) }), (document.receiver && { Receptor: mapPerson(document.receiver) })), { CondicionVenta: document.conditionSale, PlazoCredito: document.deadlineCredit, DetalleServicio: mapOrderLinesToAtvFormat(document.orderLines, docName), ResumenFactura: mapSummaryInvoice(document, docName) }), (document.referenceInformation && { InformacionReferencia: mapReferenceInformation(document.referenceInformation) })), { Otros: document.others }); return { [key]: doc }; }; exports.mapDocumentToAtvFormat = mapDocumentToAtvFormat; const mapReceptorMessageToAtvFormat = (props) => { return { MensajeReceptor: { Clave: props.clave, NumeroCedulaEmisor: props.emitterIdentifier, FechaEmisionDoc: props.documentIssueDate.toISOString(), Mensaje: props.aceptationState.toString(), // 1 Aceptado | 2 Aceptado Parcialmente | 3 Rechazado DetalleMensaje: props.aceptationDetailMessage, MontoTotalImpuesto: props.totalTaxes, CodigoActividad: props.activityCode, CondicionImpuesto: props.taxCondition, MontoTotalDeGastoAplicable: props.totalSale, // fullInvoice.ResumenFactura.TotalVenta, // TODO investigar casos de uso TotalFactura: props.totalSale, // fullInvoice.ResumenFactura.TotalVenta, NumeroCedulaReceptor: props.receptorIdentifier, NumeroConsecutivoReceptor: props.receptorConcecutive } }; }; exports.mapReceptorMessageToAtvFormat = mapReceptorMessageToAtvFormat; //# sourceMappingURL=billDocToAtv.js.map