UNPKG

@cfdi/xml

Version:

Generacion, sellado y timbrado de XML CFDI 4.0 para Node.js - facturacion electronica Mexico

843 lines (842 loc) 21.9 kB
import a from "fs"; import { Certificate as b, PrivateKey as E } from "@cfdi/csd"; import { Schema as r } from "@cfdi/xsd"; import S from "os"; import O from "path"; import { Transform as A } from "@cfdi/transform"; import { Transform as g } from "@saxon-he/cli"; import h from "xml-js"; const R = (o) => o.join(" "), c = (o, t) => { const e = {}; return t.forEach((i) => { i in o && (e[i] = o[i]); }), Object.keys(o).forEach((i) => { i in e || (e[i] = o[i]); }), e; }; class I { xml = { _declaration: { _attributes: { version: "1.0", encoding: "utf-8" } } }; tc = "cfdi:Comprobante"; version = "4.0"; XMLSchema = "http://www.w3.org/2001/XMLSchema-instance"; cfd = "http://www.sat.gob.mx/cfd/4"; locations = [ "http://www.sat.gob.mx/cfd/4", "http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd" ]; schema = r.of(); constructor(t) { const { debug: e, schema: i } = t || { debug: !1 }; this.schema.setConfig({ debug: e, path: i?.path }), this.restartCfdi(); } /** *xmlns * * @param xmlns * XmlnsLinks */ xmlns(t) { t.xsi || this.addXmlns("xsi", this.XMLSchema), t.cfdi || this.addXmlns("cfdi", this.cfd); for (const e in t) this.addXmlns(e, t[e]); } /** *addXmlns * * @param xmlnsKey * string * @param xmlns * string */ addXmlns(t, e) { this.xml["cfdi:Comprobante"]._attributes[`xmlns:${t}`] = e; } /** *addSchemaLocation * * @param locations * string[] */ addSchemaLocation(t) { const e = "xsi:schemaLocation"; this.xml["cfdi:Comprobante"]._attributes[e] || (this.xml["cfdi:Comprobante"]._attributes[e] = ""); const s = (this.xml["cfdi:Comprobante"]._attributes[e] || "").split(" "), n = Array.from( new Set([...s, ...t].filter(Boolean)) ), l = R(n); this.xml["cfdi:Comprobante"]._attributes[e] = l; } /** *setAttributesXml * * @param attr * XmlVersion */ setAttributesXml(t = {}) { const { version: e = "1.0", encoding: i = "utf-8" } = t; this.xml._declaration._attributes = { version: e, encoding: i }; } setAttributes(t = {}) { const { xmlns: e, schemaLocation: i } = t || {}; this.xmlns(e || {}), this.addSchemaLocation(i || this.locations); } comprobante(t) { const e = [ "xsi:schemaLocation", "Version", "Serie", "Folio", "Fecha", "Sello", "FormaPago", "NoCertificado", "Certificado", "CondicionesDePago", "SubTotal", "Descuento", "Moneda", "TipoCambio", "Total", "TipoDeComprobante", "Exportacion", "MetodoPago", "LugarExpedicion", "Confirmacion", "xmlns:cfdi", "xmlns:xsi" ], i = c( { ...this.xml["cfdi:Comprobante"]._attributes, Version: this.version, ...t, Sello: "", NoCertificado: "", Certificado: "", SubTotal: t.SubTotal, Descuento: t.Descuento, Total: t.Total }, e ); this.xml["cfdi:Comprobante"]._attributes = i, this.schema.cfdi.comprobante.validateInit(this.xml["cfdi:Comprobante"]._attributes); } /** *informacionGlobal * * @param payload * informacionGlobal * @param payload.Periodicidad * string * @param payload.Meses * string * @param payload.Año * string */ informacionGlobal(t) { this.schema.cfdi.informacionGlobal.validate(t), this.xml["cfdi:Comprobante"] = { "cfdi:InformacionGlobal": { _attributes: t }, ...this.xml["cfdi:Comprobante"] }; } /** *relacionados * * @param relationCfdi * Relacionado */ relacionados(t) { this.xml["cfdi:Comprobante"] = { "cfdi:CfdiRelacionados": t.getRelation(), ...this.xml["cfdi:Comprobante"] }; } /** *emisor * * @param emisor * Emisor */ emisor(t) { this.xml["cfdi:Comprobante"]["cfdi:Emisor"] = t.emisor; } /** *receptor * * @param receptor * Receptor */ receptor(t) { this.xml["cfdi:Comprobante"]["cfdi:Receptor"] = t.receptor; } /** *concepto * * @param concept * Concepts */ concepto(t) { if (t.isComplement()) { const e = t.getComplementProperties(); this.addXmlns(e.xmlnskey, e.xmlns), this.addSchemaLocation(e.schemaLocation); } this.xml["cfdi:Comprobante"]["cfdi:Conceptos"] || (this.xml["cfdi:Comprobante"]["cfdi:Conceptos"] = { "cfdi:Concepto": [] }), this.xml["cfdi:Comprobante"]["cfdi:Conceptos"]["cfdi:Concepto"].push( t.getConcept() ); } /** *impuesto * * @param impuesto * Impuestos */ impuesto(t) { this.xml["cfdi:Comprobante"]["cfdi:Impuestos"] = t.impuesto; } /** *complemento * * @param complements * ComlementType */ complemento(t) { this.xml["cfdi:Comprobante"]["cfdi:Complemento"] || (this.xml["cfdi:Comprobante"]["cfdi:Complemento"] = {}); const e = t.getComplement(); this.addXmlns(e.xmlnskey, e.xmlns), this.addSchemaLocation(e.schemaLocation), this.xml["cfdi:Comprobante"]["cfdi:Complemento"][e.key] = e.complement; } setCertificado(t) { t && (this.xml["cfdi:Comprobante"]._attributes.Certificado = t); } setNoCertificado(t) { t && (this.xml["cfdi:Comprobante"]._attributes.NoCertificado = t); } setSello(t) { t && (this.xml["cfdi:Comprobante"]._attributes.Sello = t); } restartCfdi() { this.xml = { _declaration: { _attributes: { version: "1.0", encoding: "utf-8" } } }, this.xml["cfdi:Comprobante"] = { _attributes: {}, "cfdi:Emisor": {}, "cfdi:Receptor": {} }, this.setAttributes(); } get xmlObject() { return this.xml; } } class p { /** *generateNameTemp * * @returns {string} */ static generateNameTemp() { return Date.now().toString(); } /** *readFileSync * * @param file * string */ static readFileSync(t) { return a.readFileSync(t, "utf8"); } static getTmpFullPath(t) { return O.join(S.tmpdir(), `${t}.xml`); } } class d { static info(t, ...e) { console.log(`INFO: ${t}`, ...e); } static error(t, ...e) { console.error(`ERROR: ${t}`, ...e); } static warn(t, ...e) { console.warn(`WARN: ${t}`, ...e); } } class f { code; details; name; message; method = ""; constructor({ message: t, code: e, details: i, name: s, method: n }) { this.message = t, this.code = e, this.details = i, this.name = s || "XmlError", this.method = n || ""; } setName(t) { t && (this.name = t); } setMethod(t) { t && (this.method = t); } toString() { return `${this.name}: ${this.message} ${this.method}`; } } function u({ e: o, name: t, method: e, debug: i = !1 }) { if (o instanceof f) return o.setName(t), o.setMethod(e), i && d.error(o.toString()), o; if (o instanceof Error) { const n = new f({ message: o.message, code: "error", method: e, //details: e, name: t }); return i && d.error(n.toString()), n; } const s = new f({ message: String(o), code: "error", name: t, method: e }); return i && d.error(s.toString()), s; } class $ extends I { _cadenaOriginal = ""; saxon = void 0; xslt = null; debug = !1; /** *constructor * * @param attr * Comprobante * @param options *Options; */ constructor(t) { super(t), this.xslt = t?.xslt, this.saxon = t?.saxon, this._cadenaOriginal = "", this.setDebug(!!t?.debug); } /** * certificar * * @param {string} cerpath * string */ certificar(t) { try { const e = b.fromFileSync(t); return this.setNoCertificado(e.noCertificado()), this.setCertificado(e.toBase64()), this; } catch (e) { throw u({ e, method: "certificar", debug: this.debug, name: "@cfdi/csd" }); } } /** * sellar * * @param {string} keyfile * string * @param {string} password * string */ async sellar(t, e) { const i = await this.generarCadenaOriginal(), s = await this.generarSello(i, t, e); this._cadenaOriginal = i, this.setSello(s); } /** *getJsonCdfi */ getJsonCdfi() { return this.xml; } /** *getXmlCdfi */ getXmlCdfi() { const t = { compact: !0, ignoreComment: !0, spaces: 4 }, e = h.js2xml({ ...this.xml }, t); return this.restartCfdi(), e; } /** *saveFile * * @param file * string * @param pathSave * string * @param name * string */ saveFile(t, e, i) { try { const s = `${e}${i}.xml`; return a.writeFileSync(s, Buffer.from(t, "base64"), "utf8"), !0; } catch { return !1; } } /** *getCadenaOriginal */ generarCadenaOriginal() { if (!this.xslt) throw new Error( "¡Ups! Direcction Not Found Extensible Stylesheet Language Transformation" ); try { const t = p.getTmpFullPath(p.generateNameTemp()), e = { compact: !0, ignoreComment: !0, spaces: 4 }, i = h.js2xml(this.xml, e); a.writeFileSync(t, i, "utf8"); let s; return this.saxon ? s = new g(this.saxon).s(t).xsl(String(this.xslt.path)).warnings("silent").run() : s = new A().s(t).xsl(String(this.xslt.path)).warnings("silent").run(), this.debug && (console.log("xslt =>", this.xslt), console.log("cadena original =>", s)), a.unlinkSync(t), s; } catch (t) { throw u({ e: t, method: "getCadenaOriginal", debug: this.debug, name: "@cfdi/xml" }); } } /** *getSello * * @param cadenaOriginal * string * @param keyfile * string * @param password * string */ generarSello(t, e, i) { try { return E.fromFileSync(e, i).sign(t); } catch (s) { throw u({ e: s, method: "getSello", debug: this.debug, name: "@cfdi/xml => @cfdi/csd" }); } } get sello() { return this.xml["cfdi:Comprobante"]?._attributes?.Sello || ""; } get cadenaOriginal() { return this._cadenaOriginal; } get isBebug() { return this.debug; } setDebug(t) { this.debug = t; } } class j { relacionada = {}; /** * constructor * * @param typeRelation * XmlRelacionadosAttributes */ constructor(t) { r.of().cfdi.relacionados.validate(t), this.relacionada._attributes = t; } /** *addRelation * * @param uuid * string */ addRelation(t) { this.relacionada["cfdi:CfdiRelacionado"] || (this.relacionada["cfdi:CfdiRelacionado"] = []); const e = { UUID: t }; r.of().cfdi.relacionado.validate(e), this.relacionada["cfdi:CfdiRelacionado"].push({ _attributes: e }); } /** *getRelation */ getRelation() { return this.relacionada; } toJson() { return this.relacionada; } } class J { emisor = { _attributes: { Rfc: "", Nombre: "", RegimenFiscal: "" } }; /** *constructor * * @param emisor * XmlEmisorAttribute */ constructor(t) { r.of().cfdi.emisor.validate(t), this.emisor._attributes = t; } setRfc(t) { this.emisor._attributes.Rfc = t; } setNombre(t) { this.emisor._attributes.Nombre = t; } setRegimenFiscal(t) { this.emisor._attributes.RegimenFiscal = t; } setFacAtrAdquirente(t) { this.emisor._attributes.FacAtrAdquirente = t; } /** *toJson * * @returns XmlEmisor */ toJson() { return r.of().cfdi.emisor.validate(this.emisor._attributes), this.emisor; } } class k { receptor = { _attributes: { Rfc: "", Nombre: "", UsoCFDI: "", DomicilioFiscalReceptor: "", RegimenFiscalReceptor: "" } }; /** *constructor * * @param receptor * XmlReceptorAttribute */ constructor(t) { r.of().cfdi.receptor.validate(t), this.receptor._attributes = t; } setRFC(t) { this.receptor._attributes.Rfc = t; } setNombre(t) { this.receptor._attributes.Nombre = t; } setUsoCFDI(t) { this.receptor._attributes.UsoCFDI = t; } setDomicilioFiscalReceptor(t) { this.receptor._attributes.DomicilioFiscalReceptor = t; } setResidenciaFiscal(t) { this.receptor._attributes.ResidenciaFiscal = t; } setNumRegIdTrib(t) { this.receptor._attributes.NumRegIdTrib = t; } setRegimenFiscalReceptor(t) { this.receptor._attributes.RegimenFiscalReceptor = t; } /** *toJson * * @returns XmlReceptor */ toJson() { return r.of().cfdi.receptor.validate(this.receptor._attributes), this.receptor; } } class C { impuesto = {}; /** *constructor * * @param TotalImpuestos * XmlImpuestosTrasladados */ constructor(t = {}) { if (Object.keys(t).length !== 0) { const e = t; r.of().cfdi.impuestos.validate(e); const i = c(e, ["TotalImpuestosRetenidos", "TotalImpuestosTrasladados"]); this.impuesto._attributes = i; } } /** *traslados * * @param traslado * XmlTranRentAttributesProperties */ setTraslado(t) { this.impuesto["cfdi:Traslados"] || (this.impuesto["cfdi:Traslados"] = { "cfdi:Traslado": [] }); const i = { _attributes: c(t, ["Base", "Impuesto", "TipoFactor", "TasaOCuota", "Importe"]) }; return this.impuesto["cfdi:Traslados"]["cfdi:Traslado"].push(i), this; } /** *retenciones * * @param retencion * Omit< XmlTranRentAttributesProperties, 'Base' | 'TipoFactor' | 'TasaOCuota' > */ setRetencion(t) { this.impuesto["cfdi:Retenciones"] || (this.impuesto["cfdi:Retenciones"] = { "cfdi:Retencion": [] }); const i = { _attributes: c(t, ["Base", "Impuesto", "TipoFactor", "TasaOCuota", "Importe"]) }; return this.impuesto["cfdi:Retenciones"]["cfdi:Retencion"].push(i), this; } getTotalImpuestos() { return this.impuesto._attributes; } getRetenciones() { return this.impuesto["cfdi:Retenciones"]["cfdi:Retencion"]; } getTraslados() { return this.impuesto["cfdi:Traslados"]["cfdi:Traslado"]; } } class Y extends C { // private conceptComplemnets: any = [ // { // key: 'aerolineas:Aerolineas', // schemaLocation: [ // 'http://www.sat.gob.mx/terceros', // 'http://www.sat.gob.mx/sitio_internet/cfd/terceros/terceros11.xsd', // ], // xmlns: 'http://www.sat.gob.mx/terceros', // xmlnskey: 'terceros', // }, // { // key: 'ventavehiculos:VentaVehiculos', // schemaLocation: [ // 'http://www.sat.gob.mx/ventavehiculos', // 'http://www.sat.gob.mx/sitio_internet/cfd/ventavehiculos/ventavehiculos11.xsd', // ], // xmlns: 'http://www.sat.gob.mx/ventavehiculos', // xmlnskey: 'ventavehiculos', // }, // ]; existComplemnt = !1; complementProperties = {}; concepto = {}; /** *constructor * * @param concepto * XmlConceptoAttributes */ constructor(t) { super(); const e = { ...t }; this.existComplemnt = !1, r.of().concepto.concepto.validate(e), this.concepto._attributes = e; } /** *complemento * * @param data * ComlementTypeConcept */ complemento(t) { this.concepto["cfdi:ComplementoConcepto"] || (this.concepto["cfdi:ComplementoConcepto"] = {}), this.existComplemnt = !0; const { complement: e, key: i, schemaLocation: s, xmlns: n, xmlnskey: l } = t.getComplement(); this.complementProperties.key = i, this.complementProperties.xmlns = n, this.complementProperties.xmlnskey = l, this.complementProperties.schemaLocation = s, this.concepto["cfdi:ComplementoConcepto"][i] = e; } /** *terceros * * @param cuenta * XmlConceptoTercerosAttributes */ terceros(t) { return r.of().concepto.terceros.validate(t), this.concepto["cfdi:ACuentaTerceros"] = { _attributes: t }, this; } /** *predial * * @param cuenta * string */ predial(t) { const e = { Numero: t }; return r.of().concepto.predial.validate(e), this.concepto["cfdi:CuentaPredial"] = { _attributes: e }, this; } /** *parte * * @param parte * XmlConceptParteAttributes */ parte(t) { const e = { ...t, Cantidad: Number(t.Cantidad), ValorUnitario: Number(t.ValorUnitario), Importe: Number(t.ValorUnitario) }; return r.of().concepto.parte.validate(e), this.concepto["cfdi:Parte"] = { _attributes: e }, this; } aduana(t) { const e = { NumeroPedimento: t }; return r.of().concepto.informacionAduanera.validate(e), { _attributes: e }; } setParteInformacionAduanera(t) { return this.concepto["cfdi:Parte"] ? (this.concepto["cfdi:Parte"]["cfdi:InformacionAduanera"] || (this.concepto["cfdi:Parte"]["cfdi:InformacionAduanera"] = []), this.concepto["cfdi:Parte"]["cfdi:InformacionAduanera"].push( this.aduana(t) ), this) : (console.log("utilize primero parte"), this); } /** *aduana * * @param pedimento * number | string */ InformacionAduanera(t) { return this.concepto["cfdi:InformacionAduanera"] || (this.concepto["cfdi:InformacionAduanera"] = []), this.concepto["cfdi:InformacionAduanera"].push(this.aduana(t)), this; } /** *traslado * * @param traslado * XmlTranRentAttributesProperties */ traslado(t) { const e = { ...t }; return r.of().concepto.traslado.validate(e), this.setTraslado(e), this.concepto["cfdi:Impuestos"] = this.impuesto, this; } /** *retencion * * @param retencion * XmlTranRentAttributesProperties */ retencion(t) { const e = { ...t //Importe: Number(payload.Importe), }; return this.setRetencion(e), this.concepto["cfdi:Impuestos"] = this.impuesto, this; } /** *getConcept */ getConcept() { const t = { ...this.concepto }; return this.concepto = {}, t; } /** *isComplement */ isComplement() { return this.existComplemnt; } /** *getComplementProperties */ getComplementProperties() { return this.complementProperties; } } class q extends C { constructor(t = {}) { super(t); } traslados(t) { const e = { ...t }; return r.of().cfdi.traslado.validate(e), this.setTraslado(e), this; } retenciones(t) { const e = { ...t }; return r.of().cfdi.retencion.validate(e), this.setRetencion(e), this; } } var N = /* @__PURE__ */ ((o) => (o.NoobjetoDeimpuesto = "01", o.SíObjetoDeImpuesto = "02", o.SíObjetoDeImpuestoYNobligadoAlDesglose = "03", o))(N || {}), D = /* @__PURE__ */ ((o) => (o.INGRESO = "I", o.EGRESO = "E", o.TRASLADO = "T", o.NOMINA = "N", o.PAGO = "P", o))(D || {}), x = /* @__PURE__ */ ((o) => (o.NOTA_DE_CREDITO = "01", o.NOTA_DE_DEBITO = "02", o.DELOVUCION_DE_MERCANCIA = "03", o.SUSTITUCION_DE_CFDI_PREVIOS = "04", o.TRASLADOS_DE_MERCANCIA_FACTURADOS_PREVIAMENTE = "05", o.FACTURA_POR_TRASLADOS_PREVIOS = "06", o.APLICACION_DE_ANTICIPO = "07", o.PAGOS_EN_PARCIALIDADES = "08", o.PAGOS_DIFERIDOS = "09", o))(x || {}), P = /* @__PURE__ */ ((o) => (o.GENERAL_LEY_DE_PERSONAS_MORALES = "601", o.PERSONAS_MORALES_CON_FINES_NO_LUCRATIVOS = "603", o.SUELDOS_Y_SALARIOS = "605", o.ARRENDAMIENTO = "606", o.DEMAS_INGRESOS = "608", o.CONSOLIDACION = "609", o.RESIDENTES_EN_EL_EXTRANJERO = "610", o.INGRESOS_POR_DIVIDENDOS_SOCIOS_Y_ACCIONISTAS = "611", o.PERSONAS_FISICAS_CON_ACTIVIDADES_EMPRESARIALES_Y_PROFESIONALES = "612", o.INGRESOS_POR_INTERESES = "614", o.SIN_OBLIGACIONES_FISCALES = "616", o.SOCIEDADES_COOPERATIVAS_DE_PRODUCCION = "620", o.REGIMEN_DE_INCORPORACION_FISCAL = "621", o.ACTIVIDADES_AGRICOLAS_GANADERAS_SILVICOLAS_Y_PESQUERAS = "622", o.OPCIONAL_PARA_GRUPOS_DE_SOCIEDADES = "623", o.COORDINADOS = "624", o.HIDROCARBUROS = "628", o.REGIMEN_DE_ENAJENACION_O_ADQUISICION_DE_BIENES = "607", o.PREFERENTES_Y_EMPRESAS_MULTINACIONALES = "629", o.ENAJENACION_DE_ACCIONES_EN_BOLSA_DE_VALORES = "630", o.REGIMEN_DE_LOS_INGRESOS_POR_OBTENCION_DE_PREMIOS = "615", o))(P || {}); const _ = /* @__PURE__ */ Symbol.for("@cfdi/xml.donation-shown"), m = typeof process < "u" && process.env || {}, T = m.NODE_ENV === "production", L = m.NODE_ENV === "test" || !!m.VITEST || !!m.JEST_WORKER_ID, F = globalThis[_] === !0; !T && !L && !F && (globalThis[_] = !0, console.log( [ "╔══════════════════════════════════════════════════════════╗", "║ 💛 ¿Te gusta @cfdi/xml? ¡Apóyame con una donación! 💛 ║", "╠══════════════════════════════════════════════════════════╣", "║ ☕ Buy Me a Coffee: ║", "║ https://buymeacoffee.com/recreandodev ║", "║ ║", "║ ✉️ Correo: ║", "║ amisael.amir.misael@gmail.com ║", "║ (escríbeme y te paso mi número de cuenta) ║", "║ ║", "║ 🛠️ Este mensaje solo aparece en modo desarrollo ║", "╚══════════════════════════════════════════════════════════╝" ].join(` `) )); export { $ as CFDI, Y as Concepto, Y as Concepts, J as Emisor, q as Impuestos, x as InvoiceRelation, D as InvoiceType, N as ObjetoImpEnum, k as Receptor, j as Relacionado, P as TaxSystem };