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