0.7.1 • Published 2 years ago

@nodecfdi/cfdiutils-core v0.7.1

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

@nodecfdi/cfdiutils-core

Source Code Npm Node Version Support Discord Latest Version Software License Build Status Reliability Maintainability Code Coverage Violations Total Downloads

Core of CfdiUtils

:us: The documentation of this project is in spanish as this is the natural language for intented audience.

:mexico: La documentación del proyecto está en español porque ese es el lenguaje principal de los usuarios.

Acerca de @nodecfdi/cfdiutils-core

Esta es una libreria que contiene muchas clases de ayuda, es la parte principal del set de librerias cfdiutils.

Libreria inspirada por la versión para php https://github.com/eclipxe13/CfdiUtils

Instalación

npm i @nodecfdi/cfdiutils-core --save

o

yarn add @nodecfdi/cfdiutils-core

Cadena de origen

El SAT utiliza el método de generar cadenas originales para agrupar en una forma y orden determinados la información que no debería ser alterada de un CFDI.

Una vez que se cuenta con la cadena de origen, se genera una firma con la llave privada que puede ser verificada con un certificado (llave pública).

Si algún dato (que es parte de la cadena de origen) fue modificado entonces producirá un sello diferente o la verificación del sello será negativa.

Esto significa que un CFDI podría ser alterado posteriormente a su elaboración. Por ejemplo, se le puede agregar una adenda o poner/quitar formato al XML, pues ni el nodo Addenda ni el "XML Whitespace" forman parte de la cadena de origen.

Incluso, es frecuente "reparar" un CFDI que tiene errores como una adenda sin XSD o errores sintácticos como poner un número par de rutas en el atributo xsi:schemaLocation o eliminar espacios de nombres no utilizados.

Generar una cadena de origen

Para generar cadenas de origen se pueden aplicar diferentes implementaciones de la interfaz XsltBuilderInterface. La cual contiene un único método build(xmlContent: string, xsltLocation: string).

El parámetro xmlContent es el XML que se desea convertir y el parámetro xsltLocation es la ubicación del archivo XSLT (local).

Las implementaciónes incluidas son:

  • SaxonbCliBuilder: Utiliza la herramienta Saxon-B XSLT Processor desde la ejecución por línea de comandos. Esta utilería presume la implementación de Xslt versión 2. Para usarla debes hacer algo como apt-get install libsaxonb-java.

Generar la cadena de origen de un comprobante

Se puede seguir esta receta:

import { install } from '@nodecfdi/cfdiutils-common';
import { XMLSerializer, DOMImplementation, DOMParser } from '@xmldom/xmldom'; // or can use other lib implementation for example jsDom
import { XmlResolver, SaxonbCliBuilder } from '@nodecfdi/cfdiutils-core';
import { readFileSync } from 'fs';

// from version 1.2.x on @nodecfdi/cfdiutils-common required install dom resolution
install(new DOMParser(), new XMLSerializer(), new DOMImplementation());

// el contenido del cfdi
const xmlContent = readFileSync('...archivo xml', 'utf-8');

// usar el resolvedor para usar los recursos descargados
const resolver = new XmlResolver();

// el resolvedor tiene un método de ayuda para obtener la ubicación del XSLT
// dependiendo de la versión del comprobante
const location = resolver.resolveCadenaOrigenLocation('3.3');

// fabricar la cadena origen
const builder = new SaxonbCliBuilder('The executable path for SaxonB');
const cadenaOrigen = await builder.build(xmlContent, location);

Generar la cadena origen de un Timbre Fiscal Digital

A diferencia de la cadena de origen del Comprobante, la cadena de origen del Timbre Fiscal Digital sí se necesita al menos para mostrarla en la representación impresa del CFDI.

Para ello puedes utilizar la clase TfdCadenaDeOrigen. Esta clase solo funciona con TFD versiones 1.0 y 1.1. En caso de otra versión genera una excepción.

Esta clase depende de las propiedades XmlResolver para obtener los archivos XSLT y de XsltBuilder para hacer la transformación.

import { install } from '@nodecfdi/cfdiutils-common';
import { XMLSerializer, DOMImplementation, DOMParser } from '@xmldom/xmldom'; // or can use other lib implementation for example jsDom
import { TfdCadenaDeOrigen } from '@nodecfdi/cfdiutils-core';

// from version 1.2.x on @nodecfdi/cfdiutils-common required install dom resolution
install(new DOMParser(), new XMLSerializer(), new DOMImplementation());

const tfdXmlString = '<tfd:TimbreFiscalDigital xmlns:tfd="..." />';

const builder = new TfdCadenaOrigen();

// Para cambiar el XmlResolver (por omisión crea uno nuevo)
/** myXmlResolver: XmlResolver **/
builder.setXmlResolver(myXmlResolver);

const tdfCadenaOrigen = await builder.build(tfdXmlString);

Si no cuentas con el código XML del Timbre Fiscal Digital esta receta te puede ayudar:

import { install, XmlNodeUtils } from '@nodecfdi/cfdiutils-common';
import { XMLSerializer, DOMImplementation, DOMParser } from '@xmldom/xmldom'; // or can use other lib implementation for example jsDom
import { readFileSync } from 'fs';

// from version 1.2.x on @nodecfdi/cfdiutils-common required install dom resolution
install(new DOMParser(), new XMLSerializer(), new DOMImplementation());

const cfdiFile = '/facturas/.../fei-123456.xml';
const cfdi = XmlNodeUtils.nodeFromXmlString(readFileSync(cfdiFile, 'utf-8'));
const tfd = cfdi.searchNode('cfdi:Complemento', 'tfd:TimbreFiscalDigital');

// Puedes habilitar esta linea si por alguna razon no contiene el namespace xsi
// tfd.attributes().set('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');

const tfdXmlString = XmlNodeUtils.nodeToXmlString(tfd);

NodeCertificado

La clase Certificate funciona con un archivo previamente almacenado. Para extraer un certificado de un CFDI se ofrece la clase NodeCertificado.

Esta clase puede trabajar con CFDI versión 3.2, 3.3 y 4.0, toma la información de cfdi:Comprobante@Certificado utilizando CNodeInterface y provee tres métodos para trabajar con el certificado:

  • extract(): string: obtiene el contenido del certificado acorde a la versión y decodifica desde base 64.
  • save(filename: string): void: guarda el contenido extraído a una ruta.
  • obtain(): Certificate: obtiene el objeto certificado del archivo extraído.
import { install, XmlNodeUtils } from '@nodecfdi/cfdiutils-common';
import { XMLSerializer, DOMImplementation, DOMParser } from '@xmldom/xmldom'; // or can use other lib implementation for example jsDom
import { readFileSync } from 'fs';
import { NodeCertificado } from '@nodecfdi/cfdiutils-core';

// from version 1.2.x on @nodecfdi/cfdiutils-common required install dom resolution
install(new DOMParser(), new XMLSerializer(), new DOMImplementation());

const certificate = new NodeCertificado(XmlNodeUtils.nodeFromXmlString(readFileSync('/cfdis/FE-00012847.xml', 'utf-8'))).obtain();

console.log(certificate.rfc()); // algo como COSC8001137NA

Descarga de certificados desde el SAT

Es necesario descargar los certificados de los PAC para poder validar el atributo SelloCFDI del nodo tfd:TimbreFiscalDigital porque no viene incluido en la estructura.

Siendo así, se utilizan las clases SatCertificateNumber y la clase CerRetriever.

SatCertificateNumber contiene el método remoteUrl(): string que devuelve una URL que apunta a https://rdc.sat.gob.mx/rccf/.

Soporte

Puedes obtener soporte abriendo un ticket en Github.

Adicionalmente, esta librería pertenece a la comunidad OcelotlStudio, así que puedes usar los mismos canales de comunicación para obtener ayuda de algún miembro de la comunidad.

Compatibilidad

Esta librería se mantendrá compatible con al menos la versión con soporte activo de Node más reciente.

También utilizamos Versionado Semántico 2.0.0 por lo que puedes usar esta librería sin temor a romper tu aplicación.

Contribuciones

Las contribuciones con bienvenidas. Por favor lee CONTRIBUTING para más detalles y recuerda revisar el archivo CHANGELOG.

Copyright and License

The @nodecfdi/cfdiutils-core library is copyright © NodeCfdi - OcelotlStudio and licensed for use under the MIT License (MIT). Please see LICENSE for more information.