cfdi 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0903fc48e49fd6e0f6d553af571fdfb3a0ed404
4
- data.tar.gz: b7f831218d630bb45eb73ec91f4bab437c1e196a
3
+ metadata.gz: fdf6b9c68a005bb346923cad06e85e4d1209cb1b
4
+ data.tar.gz: 5eb74e5667ffe85d3a841207505766d051757476
5
5
  SHA512:
6
- metadata.gz: b71ad3abe3a7abf869c2ee6599a88315ac3e7cf4333b828d67ac13ebbac1a484f709c7e4e1a663236e939667aecc8dfe05f0583230f75fbd5fe62b35e9f0cfa5
7
- data.tar.gz: 8f7a755921d53c0b5cc3f5caaf4cae4f7cb8ca69d6cc906ba70b8cefdd829a2c8769eb32aea32f4f3b5bfd605d387a0e46f110691b3228675070cf0806bd7e00
6
+ metadata.gz: 53beb4378b46f8e5ec4e40517567022314880bea300633417a6cfb98c72bdb74e1235e3a04bf9e0197cc17d63b8f299a455723a5156b553664e03f6732c83166
7
+ data.tar.gz: 7626c0293517f697833398bd07e644f621a80f8914e9e6f3ad775a9602440d11e0b67944147b77cedd67f1e19a030d5da7dc9e15235c3d210f2ff298d87524b4
data/Rakefile CHANGED
@@ -1,5 +1,12 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
2
3
 
3
4
  task :release do
4
5
  system "gem build cfdi.gemspec"
5
- end
6
+ end
7
+
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.pattern = 'test/*_spec.rb'
10
+ end
11
+
12
+ task :test => :spec
@@ -1,4 +1,4 @@
1
- require_relative 'cfdi'
1
+ require_relative '../lib/cfdi'
2
2
  require 'json'
3
3
  require 'time'
4
4
 
@@ -10,7 +10,7 @@ certificado = CFDI::Certificado.new './data/cert.cer'
10
10
  llave = CFDI::Key.new './data/key.pem', 'somePassword'
11
11
 
12
12
  # Así instanciamos el comprobante nuevo
13
- factura = CFDI::Comprobante.new ({
13
+ factura = CFDI::Comprobante.new({
14
14
  folio: 1,
15
15
  serie: 'A',
16
16
  fecha: Time.now,
@@ -64,6 +64,16 @@ factura.conceptos << CFDI::Concepto.new({
64
64
  # Todavía no agarro bien el pedo sobre como salen los impuestos, pull request?
65
65
  factura.impuestos << {impuesto: 'IVA'}
66
66
 
67
+ factura.addenda= {
68
+ nombre: 'poo',
69
+ namespace: 'http://surrealista.mx/xsd/poo',
70
+ xsd: 'http://surrealista.mx/xsd/poo/poo.xsd',
71
+ data: {
72
+ caca: 'popo',
73
+ pipi: 'pedos'
74
+ }
75
+ }
76
+
67
77
  # Esto hace que se le agregue al comprobante el certificado y su número de serie (noCertificado)
68
78
  certificado.certifica factura
69
79
 
@@ -9,7 +9,7 @@
9
9
  <cfdi:Domicilio referencia="Sin Referencia" estado="Nutop&#xED;a" pais="Nutop&#xED;a"/>
10
10
  </cfdi:Receptor>
11
11
  <cfdi:Conceptos>
12
- <cfdi:Concepto cantidad="2" unidad="Kilos" noIdentificacion="KDV" descripcion="Verga" valorUnitario="5500.00" importe="11000.00">
12
+ <cfdi:Concepto cantidad="2" unidad="Kilos" noIdentificacion="KDV" descripcion="Verga Ción" valorUnitario="5500.00" importe="11000.00">
13
13
  <cfdi:ComplementoConcepto/>
14
14
  </cfdi:Concepto>
15
15
  </cfdi:Conceptos>
data/lib/addenda.rb ADDED
@@ -0,0 +1,19 @@
1
+ module CFDI
2
+
3
+ # Un concepto del comprobante
4
+ class Addenda
5
+
6
+ attr_accessor *[:nombre, :namespace, :xsd, :data]
7
+
8
+ def initialize data={}
9
+ #puts self.class
10
+ data.each do |k,v|
11
+ method = "#{k}=".to_sym
12
+ next if !self.respond_to? method
13
+ self.send method, v
14
+ end
15
+ end
16
+
17
+ end #Addenda
18
+
19
+ end #CFDI
data/lib/cfdi.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  gem 'nokogiri', '< 1.6', '>= 1.4.0'
3
3
 
4
4
  require_relative 'comun.rb'
5
+ require_relative 'addenda.rb'
5
6
  require_relative 'comprobante.rb'
6
7
  require_relative 'entidad.rb'
7
8
  require_relative 'concepto.rb'
@@ -20,6 +21,6 @@ module CFDI
20
21
  require 'base64'
21
22
 
22
23
  # La versión de este gem
23
- VERSION = '0.1.5'
24
+ VERSION = '0.1.6'
24
25
 
25
26
  end
data/lib/comprobante.rb CHANGED
@@ -9,6 +9,8 @@ module CFDI
9
9
  # @private
10
10
  @@data = @@datosCadena+[:emisor, :receptor, :conceptos, :serie, :folio, :sello, :noCertificado, :certificado, :conceptos, :complemento, :cancelada, :impuestos]
11
11
  attr_accessor *@@data
12
+
13
+ @addenda = nil
12
14
 
13
15
  @@options = {
14
16
  tasa: 0.16,
@@ -66,6 +68,12 @@ module CFDI
66
68
  end
67
69
  end
68
70
 
71
+
72
+ def addenda= addenda
73
+ addenda = Addenda.new addenda unless addenda.is_a? Addenda
74
+ @addenda = addenda
75
+ end
76
+
69
77
 
70
78
  # Regresa el subtotal de este comprobante, tomando el importe de cada concepto
71
79
  #
@@ -174,6 +182,12 @@ module CFDI
174
182
  ns[:TipoCambio] = @TipoCambio if @TipoCambio
175
183
  ns[:NumCtaPago] = @NumCtaPago if @NumCtaPago && @NumCtaPago!=''
176
184
 
185
+ if (@addenda)
186
+ # Si tenemos addenda, entonces creamos el campo "xmlns:ElNombre" y agregamos sus definiciones al SchemaLocation
187
+ ns["xmlns:#{@addenda.nombre}"] = @addenda.namespace
188
+ ns['xsi:schemaLocation'] += ' '+[@addenda.namespace, @addenda.xsd].join(' ')
189
+ end
190
+
177
191
  if @noCertificado
178
192
  ns[:noCertificado] = @noCertificado
179
193
  ns[:certificado] = @certificado
@@ -224,6 +238,21 @@ module CFDI
224
238
 
225
239
  end
226
240
  }
241
+
242
+ if (@addenda)
243
+ xml.Addenda {
244
+ @addenda.data.each do |k,v|
245
+ if v.is_a? Hash
246
+ xml[@addenda.nombre].send(k, v)
247
+ elsif v.is_a? Array
248
+ xml[@addenda.nombre].send(k, v)
249
+ else
250
+ xml[@addenda.nombre].send(k, v)
251
+ end
252
+ end
253
+ }
254
+ end
255
+
227
256
  end
228
257
  end
229
258
  @builder.to_xml
data/lib/comun.rb CHANGED
@@ -8,6 +8,26 @@ class Float
8
8
  sprintf('%.2f', self)
9
9
  end
10
10
 
11
+ end
12
+ # Y quiero que los strings no tengan espacios extraños
13
+ class String
14
+
15
+ # Limpia whitespace de extremos y espacios repetidos
16
+ #
17
+ # @return [String] Una copia del string sin espacios extraños
18
+ def squish
19
+ dup.squish!
20
+ end
21
+
22
+ # Lo mismo que squish, pero destructivo
23
+ #
24
+ # @return [String] El string original sin espacios extraños
25
+ def squish!
26
+ strip!
27
+ gsub!(/\s(\s+)/, ' ')
28
+ self
29
+ end
30
+
11
31
  end
12
32
 
13
33
  module CFDI
data/lib/concepto.rb CHANGED
@@ -25,7 +25,7 @@ module CFDI
25
25
  #
26
26
  # @return [String] La descripción como string sin espacios extraños
27
27
  def descripcion= descripcion
28
- @descripcion = descripcion.strip
28
+ @descripcion = descripcion.squish
29
29
  @descripcion
30
30
  end
31
31
 
@@ -40,7 +40,7 @@ describe CFDI::Comprobante do
40
40
 
41
41
  it "debe de generar un comprobante desde XML" do
42
42
  comprobante = CFDI.from_xml(File.read('./examples/data/cfdi.xml'))
43
- returns = {:version=>"3.2", :fecha=>"2013-10-15T01:33:32", :tipoDeComprobante=>"ingreso", :formaDePago=>"PAGO EN UNA SOLA EXHIBICION", :condicionesDePago=>"Sera marcada como pagada en cuanto el receptor haya cubierto el pago.", :subTotal=>11000.0, :TipoCambio=>1, :moneda=>"pesos", :total=>12760.0, :metodoDePago=>"Transferencia Bancaria", :lugarExpedicion=>"Nutopia, Nutopia", :NumCtaPago=>nil, :emisor=>{:rfc=>"XAXX010101000", :nombre=>"Me cago en sus estándares S.A. de C.V.", :domicilioFiscal=>{:calle=>"Calle Feliz", :noExterior=>"42", :noInterior=>"314", :colonia=>"Centro", :localidad=>"No se que sea esto, pero va", :referencia=>"Sin Referencia", :municipio=>"Nutopía", :estado=>"Nutopía", :pais=>"Nutopía", :codigoPostal=>"31415"}, :expedidoEn=>{:calle=>"Calle Feliz", :noExterior=>"42", :noInterior=>nil, :colonia=>"Centro", :localidad=>"No se que sea esto, pero va", :referencia=>"Sin Referencia", :municipio=>"Nutopía", :estado=>"Nutopía", :pais=>"Nutopía", :codigoPostal=>"31415"}, :regimenFiscal=>"Pruebas Fiscales"}, :receptor=>{:rfc=>"XAXX010101000", :nombre=>"El SAT apesta S. de R.L.", :domicilioFiscal=>{:calle=>nil, :noExterior=>nil, :noInterior=>nil, :colonia=>nil, :localidad=>nil, :referencia=>"Sin Referencia", :municipio=>nil, :estado=>"Nutopía", :pais=>"Nutopía", :codigoPostal=>nil}, :expedidoEn=>nil, :regimenFiscal=>nil}, :conceptos=>[{:cantidad=>2, :unidad=>"Kilos", :noIdentificacion=>"KDV", :descripcion=>"Verga", :valorUnitario=>5500.0, :importe=>11000.0}], :serie=>nil, :folio=>"1", :sello=>"igFu7Q9Z98n6xFSLMv7a2y8ZlJCO+pgTX3xDAUt5xSpX3dHOKXkTHBAf4P/oHHDm3xkYkaNBfPEzpVFDrRVjL2rvkR5T9rsFqb4cl6DOo4RrRIpSR9vojLp7mFWiON9H6OFPi2b9PVAnyIx1Skb5iGIAmSQIhVYyt2DSauObY2c=", :noCertificado=>"20001000000200000293", :certificado=>"MIIE2jCCA8KgAwIBAgIUMjAwMDEwMDAwMDAyMDAwMDAyOTMwDQYJKoZIhvcNAQEFBQAwggFcMRowGAYDVQQDDBFBLkMuIDIgZGUgcHJ1ZWJhczEvMC0GA1UECgwmU2VydmljaW8gZGUgQWRtaW5pc3RyYWNpw7NuIFRyaWJ1dGFyaWExODA2BgNVBAsML0FkbWluaXN0cmFjacOzbiBkZSBTZWd1cmlkYWQgZGUgbGEgSW5mb3JtYWNpw7NuMSkwJwYJKoZIhvcNAQkBFhphc2lzbmV0QHBydWViYXMuc2F0LmdvYi5teDEmMCQGA1UECQwdQXYuIEhpZGFsZ28gNzcsIENvbC4gR3VlcnJlcm8xDjAMBgNVBBEMBTA2MzAwMQswCQYDVQQGEwJNWDEZMBcGA1UECAwQRGlzdHJpdG8gRmVkZXJhbDESMBAGA1UEBwwJQ295b2Fjw6FuMTQwMgYJKoZIhvcNAQkCDCVSZXNwb25zYWJsZTogQXJhY2VsaSBHYW5kYXJhIEJhdXRpc3RhMB4XDTEyMTAyNjE5MjI0M1oXDTE2MTAyNjE5MjI0M1owggFTMUkwRwYDVQQDE0BBU09DSUFDSU9OIERFIEFHUklDVUxUT1JFUyBERUwgRElTVFJJVE8gREUgUklFR08gMDA0IERPTiBNQVJUSU4gMWEwXwYDVQQpE1hBU09DSUFDSU9OIERFIEFHUklDVUxUT1JFUyBERUwgRElTVFJJVE8gREUgUklFR08gMDA0IERPTiBNQVJUSU4gQ09BSFVJTEEgWSBOVUVWTyBMRU9OIEFDMUkwRwYDVQQKE0BBU09DSUFDSU9OIERFIEFHUklDVUxUT1JFUyBERUwgRElTVFJJVE8gREUgUklFR08gMDA0IERPTiBNQVJUSU4gMSUwIwYDVQQtExxBQUQ5OTA4MTRCUDcgLyBIRUdUNzYxMDAzNFMyMR4wHAYDVQQFExUgLyBIRUdUNzYxMDAzTURGUk5OMDkxETAPBgNVBAsTCFNlcnZpZG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlrI9loozd+UcW7YHtqJimQjzX9wHIUcc1KZyBBB8/5fZsgZ/smWS4Sd6HnPs9GSTtnTmM4bEgx28N3ulUshaaBEtZo3tsjwkBV/yVQ3SRyMDkqBA2NEjbcum+e/MdCMHiPI1eSGHEpdESt55a0S6N24PW732Xm3ZbGgOp1tht1wIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQUFAAOCAQEAuoPXe+BBIrmJn+IGeI+m97OlP3RC4Ct3amjGmZICbvhI9BTBLCL/PzQjjWBwU0MG8uK6e/gcB9f+klPiXhQTeI1YKzFtWrzctpNEJYo0KXMgvDiputKphQ324dP0nzkKUfXlRIzScJJCSgRw9ZifKWN0D9qTdkNkjk83ToPgwnldg5lzU62woXo4AKbcuabAYOVoC7owM5bfNuWJe566UzD6i5PFY15jYMzi1+ICriDItCv3S+JdqyrBrX3RloZhdyXqs2Htxfw4b1OcYboPCu4+9qM3OV02wyGKlGQMhfrXNwYyj8huxS1pHghEROM2Zs0paZUOy+6ajM+Xh0LX2w==", :complemento=>nil, :cancelada=>nil, :impuestos=>[{:impuesto=>"IVA"}]}
43
+ returns = {:version=>"3.2", :fecha=>"2013-10-15T01:33:32", :tipoDeComprobante=>"ingreso", :formaDePago=>"PAGO EN UNA SOLA EXHIBICION", :condicionesDePago=>"Sera marcada como pagada en cuanto el receptor haya cubierto el pago.", :subTotal=>11000.0, :TipoCambio=>1, :moneda=>"pesos", :total=>12760.0, :metodoDePago=>"Transferencia Bancaria", :lugarExpedicion=>"Nutopia, Nutopia", :NumCtaPago=>nil, :emisor=>{:rfc=>"XAXX010101000", :nombre=>"Me cago en sus estándares S.A. de C.V.", :domicilioFiscal=>{:calle=>"Calle Feliz", :noExterior=>"42", :noInterior=>"314", :colonia=>"Centro", :localidad=>"No se que sea esto, pero va", :referencia=>"Sin Referencia", :municipio=>"Nutopía", :estado=>"Nutopía", :pais=>"Nutopía", :codigoPostal=>"31415"}, :expedidoEn=>{:calle=>"Calle Feliz", :noExterior=>"42", :noInterior=>nil, :colonia=>"Centro", :localidad=>"No se que sea esto, pero va", :referencia=>"Sin Referencia", :municipio=>"Nutopía", :estado=>"Nutopía", :pais=>"Nutopía", :codigoPostal=>"31415"}, :regimenFiscal=>"Pruebas Fiscales"}, :receptor=>{:rfc=>"XAXX010101000", :nombre=>"El SAT apesta S. de R.L.", :domicilioFiscal=>{:calle=>nil, :noExterior=>nil, :noInterior=>nil, :colonia=>nil, :localidad=>nil, :referencia=>"Sin Referencia", :municipio=>nil, :estado=>"Nutopía", :pais=>"Nutopía", :codigoPostal=>nil}, :expedidoEn=>nil, :regimenFiscal=>nil}, :conceptos=>[{:cantidad=>2, :unidad=>"Kilos", :noIdentificacion=>"KDV", :descripcion=>"Verga Ción", :valorUnitario=>5500.0, :importe=>11000.0}], :serie=>nil, :folio=>"1", :sello=>"igFu7Q9Z98n6xFSLMv7a2y8ZlJCO+pgTX3xDAUt5xSpX3dHOKXkTHBAf4P/oHHDm3xkYkaNBfPEzpVFDrRVjL2rvkR5T9rsFqb4cl6DOo4RrRIpSR9vojLp7mFWiON9H6OFPi2b9PVAnyIx1Skb5iGIAmSQIhVYyt2DSauObY2c=", :noCertificado=>"20001000000200000293", :certificado=>"MIIE2jCCA8KgAwIBAgIUMjAwMDEwMDAwMDAyMDAwMDAyOTMwDQYJKoZIhvcNAQEFBQAwggFcMRowGAYDVQQDDBFBLkMuIDIgZGUgcHJ1ZWJhczEvMC0GA1UECgwmU2VydmljaW8gZGUgQWRtaW5pc3RyYWNpw7NuIFRyaWJ1dGFyaWExODA2BgNVBAsML0FkbWluaXN0cmFjacOzbiBkZSBTZWd1cmlkYWQgZGUgbGEgSW5mb3JtYWNpw7NuMSkwJwYJKoZIhvcNAQkBFhphc2lzbmV0QHBydWViYXMuc2F0LmdvYi5teDEmMCQGA1UECQwdQXYuIEhpZGFsZ28gNzcsIENvbC4gR3VlcnJlcm8xDjAMBgNVBBEMBTA2MzAwMQswCQYDVQQGEwJNWDEZMBcGA1UECAwQRGlzdHJpdG8gRmVkZXJhbDESMBAGA1UEBwwJQ295b2Fjw6FuMTQwMgYJKoZIhvcNAQkCDCVSZXNwb25zYWJsZTogQXJhY2VsaSBHYW5kYXJhIEJhdXRpc3RhMB4XDTEyMTAyNjE5MjI0M1oXDTE2MTAyNjE5MjI0M1owggFTMUkwRwYDVQQDE0BBU09DSUFDSU9OIERFIEFHUklDVUxUT1JFUyBERUwgRElTVFJJVE8gREUgUklFR08gMDA0IERPTiBNQVJUSU4gMWEwXwYDVQQpE1hBU09DSUFDSU9OIERFIEFHUklDVUxUT1JFUyBERUwgRElTVFJJVE8gREUgUklFR08gMDA0IERPTiBNQVJUSU4gQ09BSFVJTEEgWSBOVUVWTyBMRU9OIEFDMUkwRwYDVQQKE0BBU09DSUFDSU9OIERFIEFHUklDVUxUT1JFUyBERUwgRElTVFJJVE8gREUgUklFR08gMDA0IERPTiBNQVJUSU4gMSUwIwYDVQQtExxBQUQ5OTA4MTRCUDcgLyBIRUdUNzYxMDAzNFMyMR4wHAYDVQQFExUgLyBIRUdUNzYxMDAzTURGUk5OMDkxETAPBgNVBAsTCFNlcnZpZG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlrI9loozd+UcW7YHtqJimQjzX9wHIUcc1KZyBBB8/5fZsgZ/smWS4Sd6HnPs9GSTtnTmM4bEgx28N3ulUshaaBEtZo3tsjwkBV/yVQ3SRyMDkqBA2NEjbcum+e/MdCMHiPI1eSGHEpdESt55a0S6N24PW732Xm3ZbGgOp1tht1wIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQUFAAOCAQEAuoPXe+BBIrmJn+IGeI+m97OlP3RC4Ct3amjGmZICbvhI9BTBLCL/PzQjjWBwU0MG8uK6e/gcB9f+klPiXhQTeI1YKzFtWrzctpNEJYo0KXMgvDiputKphQ324dP0nzkKUfXlRIzScJJCSgRw9ZifKWN0D9qTdkNkjk83ToPgwnldg5lzU62woXo4AKbcuabAYOVoC7owM5bfNuWJe566UzD6i5PFY15jYMzi1+ICriDItCv3S+JdqyrBrX3RloZhdyXqs2Htxfw4b1OcYboPCu4+9qM3OV02wyGKlGQMhfrXNwYyj8huxS1pHghEROM2Zs0paZUOy+6ajM+Xh0LX2w==", :complemento=>nil, :cancelada=>nil, :impuestos=>[{:impuesto=>"IVA"}]}
44
44
  comprobante.to_h.should be_eql(returns)
45
45
  end
46
46
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfdi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Hidalgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-26 00:00:00.000000000 Z
11
+ date: 2014-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -77,6 +77,7 @@ files:
77
77
  - examples/data/_empty
78
78
  - examples/data/cfdi.xml
79
79
  - examples/desde_xml.rb
80
+ - lib/addenda.rb
80
81
  - lib/certificado.rb
81
82
  - lib/cfdi.rb
82
83
  - lib/complemento.rb