module CFDI
Comprobantes fiscales digitales por los internets
El sistema de generación y sellado de facturas es una patada en los genitales. Este gem pretende ser una bolsa de hielos. Igual va a doler, pero espero que al menos no quede moretón.
Constants
- METODOS_DE_PAGO
Porque SAT, los métodos de pago con su clave
@return [Hash] La clave y su valor como texto
- NumCtaPago
- VERSION
La versión de este gem
Public Class Methods
from_xml(data)
click to toggle source
Crea un CFDI::Comprobante
desde un string XML @param data [String, IO] El XML a parsear, según acepte Nokogiri
@return [CFDI::Comprobante] El comprobante parseado
# File lib/xml.rb, line 8 def self.from_xml(data) xml = Nokogiri::XML(data); xml.remove_namespaces! factura = Comprobante.new comprobante = xml.at_xpath('//Comprobante') emisor = xml.at_xpath('//Emisor') de = emisor.at_xpath('//DomicilioFiscal') exp = emisor.at_xpath('//ExpedidoEn') receptor = xml.at_xpath('//Receptor') dr = receptor.at_xpath('//Domicilio') factura.version = comprobante.attr('version') factura.serie = comprobante.attr('serie') factura.folio = comprobante.attr('folio') factura.fecha = Time.parse(comprobante.attr('fecha')) factura.noCertificado = comprobante.attr('noCertificado') factura.certificado = comprobante.attr('certificado') factura.sello = comprobante.attr('sello') factura.formaDePago = comprobante.attr('formaDePago') factura.condicionesDePago = comprobante.attr('condicionesDePago') factura.tipoDeComprobante = comprobante.attr('tipoDeComprobante') factura.lugarExpedicion = comprobante.attr('LugarExpedicion') factura.metodoDePago = comprobante.attr('metodoDePago') factura.moneda = comprobante.attr('Moneda') factura.NumCtaPago = comprobante.attr('NumCtaPago') factura.total = comprobante.attr('total').to_f factura.subTotal = comprobante.attr('subTotal').to_f rf = emisor.at_xpath('//RegimenFiscal') emisor = { rfc: emisor.attr('rfc'), nombre: emisor.attr('nombre'), regimenFiscal: rf && rf.attr('Regimen'), domicilioFiscal: { calle: de.attr('calle'), noExterior: de.attr('noExterior'), noInterior: de.attr('noInterior'), colonia: de.attr('colonia'), localidad: de.attr('localidad'), referencia: de.attr('referencia'), municipio: de.attr('municipio'), estado: de.attr('estado'), pais: de.attr('pais'), codigoPostal: de.attr('codigoPostal') } } if exp emisor[:expedidoEn] = { calle: exp.attr('calle'), noExterior: exp.attr('noExterior'), no_int: exp.attr('noInterior'), colonia: exp.attr('colonia'), localidad: exp.attr('localidad'), referencia: exp.attr('referencia'), municipio: exp.attr('municipio'), estado: exp.attr('estado'), pais: exp.attr('pais'), codigoPostal: exp.attr('codigoPostal') } end factura.emisor = emisor; factura.receptor = { rfc: receptor.attr('rfc'), nombre: receptor.attr('nombre') } if dr factura.receptor.domicilioFiscal = { calle: dr.attr('calle'), noExterior: dr.attr('noExterior'), noInterior: dr.attr('noInterior'), colonia: dr.attr('colonia'), localidad: dr.attr('localidad'), referencia: dr.attr('referencia'), municipio: dr.attr('municipio'), estado: dr.attr('estado'), pais: dr.attr('pais'), codigoPostal: dr.attr('codigoPostal') } end factura.conceptos = [] #puts "conceptos: #{factura.conceptos.length}" xml.xpath('//Concepto').each do |concepto| hash = { cantidad: concepto.attr('cantidad').to_f, unidad: concepto.attr('unidad'), noIdentificacion: concepto.attr('noIdentificacion'), descripcion: concepto.attr('descripcion'), valorUnitario: concepto.attr('valorUnitario').to_f } factura.conceptos << Concepto.new(hash) end timbre = xml.at_xpath('//TimbreFiscalDigital') if timbre version = timbre.attr('version'); uuid = timbre.attr('UUID') fecha = timbre.attr('FechaTimbrado') sello = timbre.attr('selloCFD') certificado = timbre.attr('noCertificadoSAT') factura.complemento = { UUID: uuid, selloCFD: sello, FechaTimbrado: fecha, noCertificadoSAT: certificado, version: version, selloSAT: timbre.attr('selloSAT') } end impuestos_node = comprobante.at_xpath('//Impuestos') traslados_node = impuestos_node.xpath('//Traslados') unless traslados_node.empty? factura.impuestos.totalImpuestosTrasladados = impuestos_node.attr('totalImpuestosTrasladados') traslados = [] traslados_node.xpath('//Traslado').each do |traslado_node| traslado = Impuestos::Traslado.new traslado.impuesto = traslado_node.attr('impuesto') if traslado_node.attr('impuesto') traslado.tasa = traslado_node.attr('tasa').to_f if traslado_node.attr('tasa') traslado.importe = traslado_node.attr('importe').to_f if traslado_node.attr('importe') traslados << traslado end factura.impuestos.traslados = traslados end retenciones_node = impuestos_node.xpath('//Retenciones') unless retenciones_node.empty? factura.impuestos.totalImpuestosRetenidos = impuestos_node.attr('totalImpuestosRetenidos') retenciones = [] retenciones_node.xpath('//Retencion').each do |retencion_node| retencion = Impuestos::Retencion.new retencion.impuesto = retencion_node.attr('impuesto') if retencion_node.attr('impuesto') retencion.tasa = retencion_node.attr('tasa').to_f if retencion_node.attr('tasa') retencion.importe = retencion_node.attr('importe').to_f if retencion_node.attr('importe') retenciones << retencion end factura.impuestos.retenciones = retenciones end factura end
metodos_de_pago()
click to toggle source
alias
# File lib/cfdi.rb, line 42 def self.metodos_de_pago METODOS_DE_PAGO end