@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
JavaScript
;
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