Module: CFDI

Defined in:
lib/cfdi.rb,
lib/xml.rb,
lib/key.rb,
lib/comun.rb,
lib/entidad.rb,
lib/concepto.rb,
lib/comprobante.rb,
lib/complemento.rb,
lib/certificado.rb

Overview

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.

Defined Under Namespace

Classes: Certificado, Complemento, Comprobante, Concepto, Domicilio, ElementoComprobante, Entidad, Key

Constant Summary

VERSION =

La versión de este gem

'0.0.9'

Class Method Summary (collapse)

Class Method Details

+ (CFDI::Comprobante) from_xml(data)

Crea un CFDI::Comprobante desde un string XML

Parameters:

  • data (String, IO)

    El XML a parsear, según acepte Nokogiri

Returns:



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# 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.subTotal = comprobante.attr('subTotal').to_f
  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')
  
  
  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'),
    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')
    }
  }
      
  
  factura.conceptos = []
  #puts "conceptos: #{factura.conceptos.length}"
  xml.xpath('//Concepto').each do |concepto|
    total = concepto.attr('importe').to_f
    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
    }
    #puts "hash: ", hash
    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
  #factura.impuestos = []
  factura.impuestos << {impuesto: 'IVA'}
  
  factura
  
end