#invoice #xml #un #electronic #de #en #mexican

cfdi

Crate for using Serde to import, deserialize and use CFDIs (Mexican Electronic Invoices) | Crate para importar CFDIs a Rust, usando Serde

3 releases

new 0.1.4 Dec 27, 2024
0.1.3 Dec 27, 2024
0.1.2 Dec 27, 2024
0.1.1 Jul 30, 2024
0.1.0 Jul 30, 2024

#2602 in Parser implementations

Download history 1/week @ 2024-09-22 5/week @ 2024-10-13 8/week @ 2024-11-03 1/week @ 2024-12-08 285/week @ 2024-12-22

286 downloads per month

MIT license

16KB
147 lines

License

MIT

CFDI.rs

Crate para Deserializar un XML de un CFDI en structs nativos en Rust.

Comprobante

El struct principal es Comprobante. Al igual que en un xml de un CFDI, es el nodo de origen.

Tambien hay structs para otros subnodos del xml, incluyendo sus atributos. Estos incluyen ['Emisor'], ['Receptor'] y ['TimbreFiscalDigital']

Este crate por el momento solo contempla la estructura más básica de un CFDI. No se intenta generar un modelo completo del estandar de los CFDI 4.0+ Hasta esta versión, solo se implementa el siguient modelo:

|-Comprobante
    |-- Emisor
         |**-> rfc
         |**-> nombre
         |**-> regimen_fiscal
    |-- Receptor
         |**-> rfc
         |**-> nombre
         |**-> regimen_fiscal
         |**-> uso_cfdi
    |-- Conceptos
    |-- Complemento (opcional) - Incluye TimbreFiscalDigital
    |**-> total
    |**-> subtotal
    |**-> fecha
    |**-> forma_de_pago
    |**-> descuento
    |**-> tipo_comprobante
    |**-> forma_de_pago


|-- Representan subnodos
|**-> representan atributos del nodo

Sin embargo, cualquier persona que necesite más detalle puede revisar el codigo fuente y de ahi basarse para agregar los subnodos que necesite. Realmente no es dificil, pero es un poco tedioso. Si agregan subnodos les agradecería hicieran un Pull Request.

Ejemplo:

Usando Comprobante:

use cfdi::{DatosPrincipales, get_datos_principales};

let path = ("path/to/file.xml");
let xml_string = std::fs::read_to_string(&path).unwrap();


if let Ok(parsed) = parse_cfdi(&xml_string) {

        println!("Emisor: {}, RFC: {}", parsed.emisor.nombre, parsed.emisor.rfc);
        println!("Receptor: {}, RFC: {}", parsed.receptor.nombre, parsed.receptor.rfc);
        println!("Subtotal:  {}", parsed.subtotal);
        println!("Total:  {}", parsed.total);
        println!("Fecha Factura:  {}", parsed.fecha);
        println!("UUID:  {}", parsed.complemento);
        println!("Fecha Timbrado:  {}", parsed.fecha_timbrado);


        // Otros datos no incluidos en [`DatosPrincipales`]:
        match &parsed.complemento {
            Some(c) => c.timbre_fiscal_digital
                .clone()
                .map(|tfd| println!("Certificado SAT: {}", tfd.no_certificado_sat),
                None => None,
       }
}

Datos Principales

DatosPrincipales es un struct que facilita recopilar en 1 solo nivel los principales atributos del cfdi. Asume que los datos se encuntran correctamente definidos en el cfdi. Además, no incluye otros datos que a veces ocupan mucho espacio, o simplemente no conviene estar manejando (ej. Sello, certificado, etc.)

use cfdi::{DatosPrincipales, get_datos_principales};

let path = ("path/to/file.xml");
let xml_string = std::fs::read_to_string(&path).unwrap();

if let Ok(parsed) = parse_cfdi(&xml_string) {
        let datos: DatosPrincipales = parsed.get_datos_principales();

        println!("Emisor: {}, RFC: {}", datos.emisor_nombre, datos.emisor_rfc);
        println!("Receptor: {}, RFC: {}", datos.receptor_nombre, datos.receptor_rfc);
        println!("Subtotal:  {}", datos.subtotal);
        println!("Total:  {}", datos.total);
        println!("Fecha Factura:  {}", datos.fecha);
        println!("UUID:  {}", datos.get_uuid());
        println!("Fecha Timbrado:  {}", datos.get_fecha_timbrado());

}

Dependencies

~1.6–2.4MB
~44K SLoC