Skip to content

Instantly share code, notes, and snippets.

@3zcurdia
Last active July 4, 2024 01:41
Show Gist options
  • Save 3zcurdia/258e9fffde9d4e5240c0a4abd5d1053a to your computer and use it in GitHub Desktop.
Save 3zcurdia/258e9fffde9d4e5240c0a4abd5d1053a to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require "nokogiri"
require "json"
module Cfdi
module_function
def parse_file(xml_path)
doc = Nokogiri::XML(File.read(xml_path))
comp = doc.xpath("//cfdi:Comprobante").first
nomina = comp.xpath("//*:Nomina").first
{
folio: comp.attribute("Folio")&.value,
serie: comp.attribute("Serie")&.value,
fecha: comp.attribute("Fecha")&.value,
emisor: comp.xpath("//cfdi:Emisor").map { |e|
{
rfc: e.attribute("Rfc")&.value,
nombre: e.attribute("Nombre")&.value,
regimen_fiscal: e.attribute("RegimenFiscal")&.value
}
},
receptor: comp.xpath("//cfdi:Receptor").map { |r|
{
rfc: r.attribute("Rfc")&.value,
nombre: r.attribute("Nombre")&.value,
uso_cfdi: r.attribute("UsoCFDI")&.value
}
},
conceptos: comp.xpath("//cfdi:Conceptos").flat_map { |c|
c.xpath("//cfdi:Concepto").map { |co|
{
clave_prod_serv: co.attribute("ClaveProdServ")&.value,
cantidad: co.attribute("Cantidad")&.value,
clave_unidad: co.attribute("ClaveUnidad")&.value,
descripcion: co.attribute("Descripcion")&.value,
valor_unitario: co.attribute("ValorUnitario")&.value,
importe: co.attribute("Importe")&.value,
descuento: co.attribute("Descuento")&.value
}
}
},
nomina: {
percepciones: nomina.xpath("//*:Percepciones").map { |e|
{
total_sueldos: e.attribute("TotalSueldos")&.value,
total_gravado: e.attribute("TotalGravado")&.value,
total_exento: e.attribute("TotalExento")&.value,
detalles: e.xpath("//*:Percepcion").map { |p|
{
tipo_percepcion: p.attribute("TipoPercepcion")&.value,
clave: p.attribute("Clave")&.value,
concepto: p.attribute("Concepto")&.value,
importe_gravado: p.attribute("ImporteGravado")&.value,
importe_exento: p.attribute("ImporteExento")&.value
}
}
}
},
deducciones: nomina.xpath("//*:Deducciones").map { |e|
{
total_otras_deducciones: e.attribute("TotalOtrasDeducciones")&.value,
total_impuestos_retenidos: e.attribute("TotalImpuestosRetenidos")&.value,
detalles: e.xpath("//*:Deduccion").map { |p|
{
tipo_deduccion: p.attribute("TipoDeduccion")&.value,
clave: p.attribute("Clave")&.value,
concepto: p.attribute("Concepto")&.value,
importe: p.attribute("Importe")&.value
}
}
}
}
}
}
end
end
if __FILE__ == $0
puts Cfdi.parse_file(ARGV[0]).to_json
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment