facturacion_electronica 0.0.1

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.
Files changed (29) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +143 -0
  6. data/Rakefile +1 -0
  7. data/facturacion_electronica.gemspec +27 -0
  8. data/lib/bill_xml_request.rb +59 -0
  9. data/lib/facturacion_electronica.rb +34 -0
  10. data/lib/facturacion_electronica/version.rb +3 -0
  11. data/lib/services/pac_provider_fm.rb +34 -0
  12. data/lib/services/pac_provider_service.rb +7 -0
  13. data/spec/docs_examples/CertificadosDemo-FM/ESI920427886/contrasen~a.txt +1 -0
  14. data/spec/docs_examples/CertificadosDemo-FM/ESI920427886/esi920427886_1210221507s.cer +0 -0
  15. data/spec/docs_examples/CertificadosDemo-FM/ESI920427886/esi920427886_1210221507s.key +0 -0
  16. data/spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/TUEM470405V4A_1210231509S.cer +0 -0
  17. data/spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/TUEM470405V4A_1210231509S.key +0 -0
  18. data/spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/contrasen~a.txt +1 -0
  19. data/spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.cer +0 -0
  20. data/spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key +0 -0
  21. data/spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key.pem +15 -0
  22. data/spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/contrasen~a.txt +1 -0
  23. data/spec/docs_examples/base_xml_file.xml +25 -0
  24. data/spec/fixtures/bill_example.rb +77 -0
  25. data/spec/lib/bill_xml_request_spec.rb +50 -0
  26. data/spec/lib/facturacion_electronica_spec.rb +203 -0
  27. data/spec/lib/services/pac_provider_fm_spec.rb +43 -0
  28. data/spec/lib/services/pac_provider_service_spec.rb +14 -0
  29. metadata +157 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f6e8f8ea64af9c7e6b657ce3245cac4c94a0123
4
+ data.tar.gz: a787b7daefc42b5fc3d6217cb9d6b43be6050303
5
+ SHA512:
6
+ metadata.gz: aa03bb42fd867ed8c53e3e54feaf0ddb7e4d9ba3dac1624660aadc7c56d88eeb260ad875e52e6f22850e8296f42da92015b89dfd50fe2259869113555ed90252
7
+ data.tar.gz: 86c27941ab92f14a8bc035f11495a6a01637d169ff0bbdacf3f1f9ff182f82aac06e8da7028262e275052233e0945f49814bdcc76a68635cae9f5f3689734c0e
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in facturacion_electronica.gemspec
4
+ gemspec
5
+
6
+ gem 'nokogiri', '< 1.6', '>= 1.4.0'
7
+ gem 'fm_timbrado_cfdi', git: 'git@github.com:crowdint/fm_timbrado_cfdi.git'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ulices Barajas
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # FacturacionElectronica
2
+
3
+ This a gem to dispatch a request of a new CFDi(comprobante fiscal
4
+ digital) through a different PAC() providers. Right now we connecting to the
5
+ FacturacionModerna web service.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'facturacion_electronica'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install facturacion_electronica
20
+
21
+ ## Usage
22
+
23
+ You need to send a request with:
24
+ - user keys: This is used for the PAC provider that you specify, the
25
+ internal structure of this hash allows it.
26
+ - PAC provider: When you send a new CFDi bill request you need to
27
+ specify the PAC provider. Currently we support FacturacionModerna.
28
+ - biller: Here we send the official documents, the ones provided by SAT to the
29
+ billers.
30
+ - bill: All the information about the bill that is requested to be
31
+ stamped through the PAC provider.
32
+
33
+ Request:
34
+ ```
35
+ { user_keys: {
36
+ id: 'UsuarioPruebasWS',
37
+ password: 'b9ec2afa3361a59af4b4d102d3f704eabdf097d4',
38
+ namespace: 'https://t2demo.facturacionmoderna.com/timbrado/soap',
39
+ endpoint: 'https://t2demo.facturacionmoderna.com/timbrado/soap',
40
+ wsdl: 'https://t2demo.facturacionmoderna.com/timbrado/wsdl',
41
+ log: false,
42
+ ssl_verify_mode: :none },
43
+ pac_provider: 'FacturacionModerna',
44
+ biller: {
45
+ certificate: CertificateFile.cer,
46
+ key: KeyFile.key.pem,
47
+ password: 'billerpass'
48
+ }
49
+ bill: {
50
+ {
51
+ factura: {
52
+ folio: '101',
53
+ serie: 'AA',
54
+ fecha: CurrentDate,
55
+ formaDePago: 'Pago en una sola exhibicion',
56
+ condicionesDePago: 'Contado',
57
+ metodoDePago: 'Cheque',
58
+ lugarExpedicion: 'San Pedro Garza Garcia, Nuevo Leon, Mexico',
59
+ NumCtaPago: 'No identificado',
60
+ moneda: 'MXN'
61
+ },
62
+ conceptos: [
63
+ { cantidad: 3,
64
+ unidad: 'PIEZA',
65
+ descripcion: 'CAJA DE HOJAS BLANCAS TAMANO CARTA',
66
+ valorUnitario: 450.00,
67
+ importe: 1350.00
68
+ },
69
+ { cantidad: 8,
70
+ unidad: 'PIEZA',
71
+ descripcion: 'RECOPILADOR PASTA DURA 3 ARILLOS',
72
+ valorUnitario: 18.50,
73
+ importe: 148.00
74
+ },
75
+ ],
76
+ emisor: {
77
+ rfc: 'TUMG620310R95',
78
+ nombre: 'FACTURACION MODERNA SA DE CV',
79
+ domicilioFiscal: {
80
+ calle: 'RIO GUADALQUIVIR',
81
+ noExterior: '238',
82
+ noInterior: '314',
83
+ colonia: 'ORIENTE DEL VALLE',
84
+ localidad: 'No se que sea esto, pero va',
85
+ referencia: 'Sin Referencia',
86
+ municipio: 'San Pedro Garza Garcia',
87
+ estado: 'Nuevo Leon',
88
+ pais: 'Mexico',
89
+ codigoPostal: '66220'
90
+ },
91
+ expedidoEn: {
92
+ calle: 'RIO GUADALQUIVIR',
93
+ noExterior: '238',
94
+ noInterior: '314',
95
+ colonia: 'ORIENTE DEL VALLE',
96
+ localidad: 'No se que sea esto, pero va',
97
+ referencia: 'Sin Referencia',
98
+ municipio: 'San Pedro Garza Garcia',
99
+ estado: 'Nuevo Leon',
100
+ pais: 'Mexico',
101
+ codigoPostal: '66220'
102
+ },
103
+ regimenFiscal: 'REGIMEN GENERAL DE LEY PERSONAS MORALES'
104
+ },
105
+ emisor_pass: 'billerpass',
106
+ cliente: {
107
+ rfc: 'XAXX010101000',
108
+ nombre: 'PUBLICO EN GENERAL',
109
+ domicilioFiscal: {
110
+ calle: 'CERRADA DE AZUCENAS',
111
+ noExterior: '109',
112
+ colonia: 'REFORMA',
113
+ municipio: 'Oaxaca de Juarez',
114
+ estado: 'Oaxaca',
115
+ pais: 'Mexico',
116
+ codigoPostal: '68050'
117
+ }
118
+ },
119
+ impuestos: {
120
+ impuesto: 'IVA'
121
+ }
122
+ }
123
+ }
124
+ }
125
+ ```
126
+
127
+ Response:
128
+ ```
129
+ {
130
+ status: true / false,
131
+ xml: bill_xml_file,
132
+ stamp: sat_stamp_file,
133
+ pdf: bill_pdf_file
134
+ }
135
+ ```
136
+
137
+ ## Contributing
138
+
139
+ 1. Fork it
140
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
141
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
142
+ 4. Push to the branch (`git push origin my-new-feature`)
143
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'facturacion_electronica/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "facturacion_electronica"
8
+ spec.version = FacturacionElectronica::VERSION
9
+ spec.authors = ["Ulices Barajas"]
10
+ spec.email = ["ulices.barajas@crowdint.com"]
11
+ spec.description = %q{Processing electronic invoices and ring through a PAC}
12
+ spec.summary = %q{Processing electronic invoices and ring through a PAC}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'cfdi'
22
+ spec.add_dependency 'fm_timbrado_cfdi'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ end
@@ -0,0 +1,59 @@
1
+ require 'cfdi'
2
+
3
+ class BillXmlRequest
4
+ def self.new_xml(*args, &block)
5
+ instance = allocate
6
+ instance.my_initialize(*args, &block)
7
+ instance
8
+ end
9
+
10
+ def my_initialize biller, bill
11
+ @certificate = CFDI::Certificado.new biller[:certificate]
12
+ @key = CFDI::Key.new biller[:key], biller[:password]
13
+ @bill = bill
14
+ end
15
+
16
+ #Generate an XML file by CFDI gem
17
+ def generate_xml_request
18
+ tax_receipt = generate_tax_receipt
19
+ @certificate.certifica tax_receipt
20
+ @key.sella tax_receipt
21
+ tax_receipt.to_xml
22
+ end
23
+
24
+ private
25
+
26
+ def bill_emissor_pass
27
+ @bill[:emisor_pass]
28
+ end
29
+
30
+ def generate_tax_receipt
31
+ tax_receipt = CFDI::Comprobante.new @bill[:factura]
32
+ tax_receipt.emisor = get_tax_receipt_emissor
33
+ tax_receipt.receptor = get_tax_receipt_receptor
34
+ set_tax_receipt_concepts tax_receipt
35
+ tax_receipt.impuestos << get_tax_receipt_taxes
36
+ tax_receipt
37
+ end
38
+
39
+ def get_tax_receipt_emissor
40
+ @bill[:emisor][:domicilioFiscal] = CFDI::Domicilio.new @bill[:emisor][:domicilioFiscal]
41
+ @bill[:emisor][:expedidoEn] = CFDI::Domicilio.new @bill[:emisor][:expedidoEn]
42
+ CFDI::Entidad.new @bill[:emisor]
43
+ end
44
+
45
+ def get_tax_receipt_receptor
46
+ @bill[:cliente][:domicilioFiscal] = CFDI::Domicilio.new @bill[:cliente][:domicilioFiscal]
47
+ CFDI::Entidad.new @bill[:cliente]
48
+ end
49
+
50
+ def set_tax_receipt_concepts tax_receipt
51
+ @bill[:conceptos].each do |concept|
52
+ tax_receipt.conceptos << CFDI::Concepto.new(concept)
53
+ end
54
+ end
55
+
56
+ def get_tax_receipt_taxes
57
+ @bill[:impuestos]
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ require 'facturacion_electronica/version'
2
+ require 'services/pac_provider_fm'
3
+ require 'bill_xml_request'
4
+
5
+ module FacturacionElectronica
6
+ PACS = { :'FacturacionModerna' => PacProviderFM }
7
+
8
+ def self.create_cfdi request
9
+ if valid_params?(request)
10
+ new_xml_request = (BillXmlRequest.new_xml request[:biller],
11
+ request[:bill]).generate_xml_request
12
+ pac_service = PacProviderFM.new new_xml_request
13
+ pac_service.rining request[:user_keys]
14
+ else
15
+ { status: false, error_msg: 'Parametros invalidos' }
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ class << self
22
+ def valid_params? request
23
+ result = true
24
+ [:user_keys, :pac_provider, :biller, :bill].each do |k|
25
+ result = (request.has_key?(k) && is_valid?(request[k])) unless result == false
26
+ end
27
+ result
28
+ end
29
+
30
+ def is_valid? param_value
31
+ !param_value.empty?
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module FacturacionElectronica
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,34 @@
1
+ require 'services/pac_provider_service'
2
+ require 'fm_timbrado_cfdi'
3
+
4
+ class PacProviderFM < PacProviderService
5
+
6
+ def rining user_keys
7
+ config_client user_keys
8
+ response = FmTimbradoCfdi.timbra_cfdi_xml(@tax_receipt_xml, true)
9
+ parse response
10
+ end
11
+
12
+ private
13
+
14
+ def parse response
15
+ { status: response.valid?,
16
+ xml: response.xml,
17
+ stamp: response.timbre || '',
18
+ pdf: response.pdf || ''
19
+ }
20
+ end
21
+
22
+ def config_client user_keys
23
+ FmTimbradoCfdi.configurar do |config|
24
+ config.user_id = user_keys[:id]
25
+ config.user_pass = user_keys[:password]
26
+ config.namespace = user_keys[:namespace]
27
+ config.endpoint = user_keys[:endpoint]
28
+ config.fm_wsdl = user_keys[:wsdl]
29
+ config.log = user_keys[:log]
30
+ config.ssl_verify_mode = user_keys[:ssl_verify_mode]
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,7 @@
1
+ class PacProviderService
2
+ attr_accessor :tax_receipt_xml
3
+
4
+ def initialize tax_receipt_xml
5
+ @tax_receipt_xml = tax_receipt_xml
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ Contraseña: 12345678a
@@ -0,0 +1 @@
1
+ Contraseña: 12345678a
@@ -0,0 +1,15 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICXAIBAAKBgQDJ37Oz12lX9bUZDy0WqxNz+VOBLcP3Bfto/fJK5SxVNYNALUnK
3
+ atude41MPedD3BSbKJ3HII1d6AM9l8M6Bw+l7/Kdt9/A06gHLtc/FULiHsRdUrDs
4
+ 2hZgTPoZSfQHZnKFSUjfOCqjLdpYUawpDcWh7Od6dHDSr5nUqYNwMLsIJQIDAQAB
5
+ AoGAIolO6RmVQCMdFGhwQkyKS3EARD1cJUq0tEWdygpjB0Dcb4JP+X1GjS6yAbUl
6
+ d4qTS+gq9gIvrT0gMM1h7O+AUYks4yFpGdQuUFQ0X4yIKbRqSHShRFG0CZPxQ29f
7
+ reDjXPK3VKgNr9mUn0ilVQsCzKnHZHdAGWrgs9QjrkgEqAECQQD2kF0Oq6LcsAoa
8
+ DeMhw3W0cV4jaS8plQp5SpJq9mqBp3p9B840roXCvXPOOfWvWIQt2S+qktTJNQaq
9
+ 8gad8a+BAkEA0ZmALLbrhVmcB80zYTFI3937dwbf3uSgz1QHFbfOv1G2iyEGEWeo
10
+ tugVcBHmRyP3vVG7+nEzoDQQSAJVTgnqpQJAKvnIrojuDydD63ymLTljZ7sm3Gc2
11
+ CDppI/ECilA/CjBF4ksc/wO4XtQkvjpN/20fRNqJO2LyYcuzSNJ8osUAgQJAMXJ6
12
+ J5Jby9DRG5IQbfx3icDPw0vO4sGjImZbaYc8ciwv2XDIArEmv0fPTuoaHmxg1LwE
13
+ kdfE6yV9Nc+/GjMCtQJBAKsLNdw/cCULEZTpSVmRCJBzZkwG+JcGnfBOkDdCkoZe
14
+ +ledGmXQwtZLt3EkourLPah1j1IVdipSVpJCUNuQjc0=
15
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ Contraseña: 12345678a
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0"?>
2
+ <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd" version="3.2" folio="4" fecha="2013-11-08T16:04:21" formaDePago="Pago en una sola exhibicion" condicionesDePago="Contado" subTotal="1498.00" Moneda="MXN" total="1737.68" metodoDePago="Cheque" tipoDeComprobante="ingreso" LugarExpedicion="San Pedro Garza Garcia, Nuevo Leon, Mexico" serie="AA" TipoCambio="1" NumCtaPago="No identificado" noCertificado="20001000000200000278" certificado="MIIEQzCCAyugAwIBAgIUMjAwMDEwMDAwMDAyMDAwMDAyNzgwDQYJKoZIhvcNAQEFBQAwggFcMRowGAYDVQQDDBFBLkMuIDIgZGUgcHJ1ZWJhczEvMC0GA1UECgwmU2VydmljaW8gZGUgQWRtaW5pc3RyYWNpw7NuIFRyaWJ1dGFyaWExODA2BgNVBAsML0FkbWluaXN0cmFjacOzbiBkZSBTZWd1cmlkYWQgZGUgbGEgSW5mb3JtYWNpw7NuMSkwJwYJKoZIhvcNAQkBFhphc2lzbmV0QHBydWViYXMuc2F0LmdvYi5teDEmMCQGA1UECQwdQXYuIEhpZGFsZ28gNzcsIENvbC4gR3VlcnJlcm8xDjAMBgNVBBEMBTA2MzAwMQswCQYDVQQGEwJNWDEZMBcGA1UECAwQRGlzdHJpdG8gRmVkZXJhbDESMBAGA1UEBwwJQ295b2Fjw6FuMTQwMgYJKoZIhvcNAQkCDCVSZXNwb25zYWJsZTogQXJhY2VsaSBHYW5kYXJhIEJhdXRpc3RhMB4XDTEyMTAyNDE3MzQ1MloXDTE2MTAyNDE3MzQ1Mlowgb0xJTAjBgNVBAMTHEdFUkFSRE8gTUFOVUVMIFRSVUpJTExPIE1PUkExJTAjBgNVBCkTHEdFUkFSRE8gTUFOVUVMIFRSVUpJTExPIE1PUkExJTAjBgNVBAoTHEdFUkFSRE8gTUFOVUVMIFRSVUpJTExPIE1PUkExFjAUBgNVBC0TDVRVTUc2MjAzMTBSOTUxGzAZBgNVBAUTElRVTUc2MjAzMTBNREZSTk4wOTERMA8GA1UECxMIQ29uZmlybWEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMnfs7PXaVf1tRkPLRarE3P5U4Etw/cF+2j98krlLFU1g0AtScpq2517jUw950PcFJsonccgjV3oAz2XwzoHD6Xv8p2338DTqAcu1z8VQuIexF1SsOzaFmBM+hlJ9AdmcoVJSN84KqMt2lhRrCkNxaHs53p0cNKvmdSpg3AwuwglAgMBAAGjHTAbMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgbAMA0GCSqGSIb3DQEBBQUAA4IBAQAHZ4swEYA6oNqyM58qEMtv+9h8jNe3fzFdmA1DMIrfXgZBSQXkuXS3AsztxEDOIu8BWUdHjW5Kd1TslODj4SSxH4ZKfaSlaF+L1/1YNjTved2pwE6HVMjgVldb630luOuTwXcWsulcd11Tqp+/0JwcKOnbU4lE/DnrdlX/XJ4RBM9ERnX4Ja71jAWHN5KHT5JPJ+zINDG6DNinX53z8iZBXo1fd+9Tt+3tBANzgljH5m8LYrb+7R0QGWvRuHsKfi8v1u4bXOnovjrSJuKUtX/yCJ12vOW7bxG61RawztggHLsdOZz4Fgcp2kQNHcbXIKodCNYylPSY3/qHmWU1hHSu" sello="s7ihc+V6rgp5rdycfb+A5yUPs1OSlpWgQkxL67Qov97nbRa4pGAzti47VUqKK6O1HUDFy9vDGzS9E4oRAwtPtKD9J67ONWXWK47/+6pJc3Gu/alTm59x2qkU7MpLbaQ5KoDGbIArzq4WSbsKcX7oM5sQqgSPEk/B3Kxw8w0Xj6I=">
3
+ <cfdi:Emisor nombre="FACTURACION MODERNA SA DE CV" rfc="TUMG620310R95">
4
+ <cfdi:DomicilioFiscal calle="RIO GUADALQUIVIR" noExterior="238" noInterior="314" colonia="ORIENTE DEL VALLE" localidad="No se que sea esto, pero va" referencia="Sin Referencia" municipio="San Pedro Garza Garcia" estado="Nuevo Leon" pais="Mexico" codigoPostal="66220"/>
5
+ <cfdi:ExpedidoEn calle="RIO GUADALQUIVIR" noExterior="238" noInterior="314" colonia="ORIENTE DEL VALLE" localidad="No se que sea esto, pero va" referencia="Sin Referencia" municipio="San Pedro Garza Garcia" estado="Nuevo Leon" pais="Mexico" codigoPostal="66220"/>
6
+ <cfdi:RegimenFiscal Regimen="REGIMEN GENERAL DE LEY PERSONAS MORALES"/>
7
+ </cfdi:Emisor>
8
+ <cfdi:Receptor nombre="PUBLICO EN GENERAL" rfc="XAXX010101000">
9
+ <cfdi:Domicilio calle="CERRADA DE AZUCENAS" noExterior="109" colonia="REFORMA" municipio="Oaxaca de Juarez" estado="Oaxaca" pais="Mexico" codigoPostal="68050"/>
10
+ </cfdi:Receptor>
11
+ <cfdi:Conceptos>
12
+ <cfdi:Concepto cantidad="3" unidad="PIEZA" descripcion="CAJA DE HOJAS BLANCAS TAMANO CARTA" valorUnitario="450.00" importe="1350.00">
13
+ <cfdi:ComplementoConcepto/>
14
+ </cfdi:Concepto>
15
+ <cfdi:Concepto cantidad="8" unidad="PIEZA" descripcion="RECOPILADOR PASTA DURA 3 ARILLOS" valorUnitario="18.50" importe="148.00">
16
+ <cfdi:ComplementoConcepto/>
17
+ </cfdi:Concepto>
18
+ </cfdi:Conceptos>
19
+ <cfdi:Impuestos totalImpuestosTrasladados="239.68">
20
+ <cfdi:Traslados>
21
+ <cfdi:Traslado impuesto="IVA" tasa="16" importe="239.68"/>
22
+ </cfdi:Traslados>
23
+ </cfdi:Impuestos>
24
+ <cfdi:Complemento/>
25
+ </cfdi:Comprobante>
@@ -0,0 +1,77 @@
1
+ module BillExample
2
+ def self.request
3
+ {
4
+ factura: {
5
+ folio: [101, 102, 103, 104, 105].sample,
6
+ serie: ['AA', 'BB', 'CC', 'DD'].sample,
7
+ fecha: Time.now,
8
+ formaDePago: 'Pago en una sola exhibicion',
9
+ condicionesDePago: 'Contado',
10
+ metodoDePago: 'Cheque',
11
+ lugarExpedicion: 'San Pedro Garza Garcia, Nuevo Leon, Mexico',
12
+ NumCtaPago: 'No identificado',
13
+ moneda: 'MXN'
14
+ },
15
+ conceptos: [
16
+ { cantidad: 3,
17
+ unidad: 'PIEZA',
18
+ descripcion: 'CAJA DE HOJAS BLANCAS TAMANO CARTA',
19
+ valorUnitario: 450.00,
20
+ importe: 1350.00
21
+ },
22
+ { cantidad: 8,
23
+ unidad: 'PIEZA',
24
+ descripcion: 'RECOPILADOR PASTA DURA 3 ARILLOS',
25
+ valorUnitario: 18.50,
26
+ importe: 148.00
27
+ },
28
+ ],
29
+ emisor: {
30
+ rfc: 'TUMG620310R95',
31
+ nombre: 'FACTURACION MODERNA SA DE CV',
32
+ domicilioFiscal: {
33
+ calle: 'RIO GUADALQUIVIR',
34
+ noExterior: '238',
35
+ noInterior: '314',
36
+ colonia: 'ORIENTE DEL VALLE',
37
+ localidad: 'No se que sea esto, pero va',
38
+ referencia: 'Sin Referencia',
39
+ municipio: 'San Pedro Garza Garcia',
40
+ estado: 'Nuevo Leon',
41
+ pais: 'Mexico',
42
+ codigoPostal: '66220'
43
+ },
44
+ expedidoEn: {
45
+ calle: 'RIO GUADALQUIVIR',
46
+ noExterior: '238',
47
+ noInterior: '314',
48
+ colonia: 'ORIENTE DEL VALLE',
49
+ localidad: 'No se que sea esto, pero va',
50
+ referencia: 'Sin Referencia',
51
+ municipio: 'San Pedro Garza Garcia',
52
+ estado: 'Nuevo Leon',
53
+ pais: 'Mexico',
54
+ codigoPostal: '66220'
55
+ },
56
+ regimenFiscal: 'REGIMEN GENERAL DE LEY PERSONAS MORALES'
57
+ },
58
+ emisor_pass: '12345678a',
59
+ cliente: {
60
+ rfc: 'XAXX010101000',
61
+ nombre: 'PUBLICO EN GENERAL',
62
+ domicilioFiscal: {
63
+ calle: 'CERRADA DE AZUCENAS',
64
+ noExterior: '109',
65
+ colonia: 'REFORMA',
66
+ municipio: 'Oaxaca de Juarez',
67
+ estado: 'Oaxaca',
68
+ pais: 'Mexico',
69
+ codigoPostal: '68050'
70
+ }
71
+ },
72
+ impuestos: {
73
+ impuesto: 'IVA'
74
+ }
75
+ }
76
+ end
77
+ end
@@ -0,0 +1,50 @@
1
+ require 'bill_xml_request'
2
+ require 'fixtures/bill_example'
3
+
4
+ describe BillXmlRequest do
5
+ let(:biller) do
6
+ {
7
+ certificate: File.open('./spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.cer'),
8
+ key: File.open('spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key.pem'),
9
+ password: '12345678a'
10
+ }
11
+ end
12
+ let(:bill) do
13
+ BillExample.request
14
+ end
15
+
16
+ context 'When construct a new bill xml with valid information' do
17
+ before do
18
+ new_xml_request = BillXmlRequest.new_xml(biller, bill)
19
+ @response = new_xml_request.generate_xml_request
20
+ end
21
+
22
+ it 'should be a xml file' do
23
+ expect(@response).to include('<?xml version="1.0"?>')
24
+ end
25
+
26
+ it 'contains Comprobante key' do
27
+ expect(@response).to include('<cfdi:Comprobante')
28
+ end
29
+
30
+ it 'using the SAT cfdi url' do
31
+ expect(@response).to include('xmlns:cfdi="http://www.sat.gob.mx/cfd/3"')
32
+ end
33
+
34
+ it 'using the SAT xsi url' do
35
+ expect(@response).to include('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
36
+ end
37
+
38
+ it 'using the SAT schemaLocation url' do
39
+ expect(@response).to include('xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd"')
40
+ end
41
+
42
+ it 'contains Certificado key' do
43
+ expect(@response).to include('certificado=')
44
+ end
45
+
46
+ it 'contains Certificado key' do
47
+ expect(@response).to include('sello=')
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,203 @@
1
+ require 'facturacion_electronica'
2
+ require 'fixtures/bill_example'
3
+
4
+ describe FacturacionElectronica do
5
+ let(:user_keys) do
6
+ { id: 'UsuarioPruebasWS',
7
+ password: 'b9ec2afa3361a59af4b4d102d3f704eabdf097d4',
8
+ namespace: 'https://t2demo.facturacionmoderna.com/timbrado/soap',
9
+ endpoint: 'https://t2demo.facturacionmoderna.com/timbrado/soap',
10
+ wsdl: 'https://t2demo.facturacionmoderna.com/timbrado/wsdl',
11
+ log: false,
12
+ ssl_verify_mode: :none
13
+ }
14
+ end
15
+ let(:biller) do
16
+ {
17
+ certificate: File.open('./spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.cer'),
18
+ key: File.open('spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key.pem'),
19
+ password: '12345678a'
20
+ }
21
+ end
22
+ let(:pac_provider){ 'FacturacionModerna' }
23
+ let(:bill) do
24
+ BillExample.request
25
+ end
26
+
27
+ describe '.create_cfdi' do
28
+ context 'When request for new cfdi with valid information' do
29
+ before do
30
+ @response = subject.create_cfdi({
31
+ user_keys: user_keys,
32
+ pac_provider: pac_provider,
33
+ biller: biller,
34
+ bill: bill})
35
+ end
36
+
37
+ it 'returns a valid stamped bill' do
38
+ expect(@response[:status]).to be_true
39
+ end
40
+
41
+ it 'contains a valid SAT rining' do
42
+ expect(@response[:xml]).to include('<cfdi:Complemento><tfd:TimbreFiscalDigital')
43
+ end
44
+ end
45
+
46
+ context 'When request for a new cfdi with invalid params' do
47
+ context 'and user keys' do
48
+ let(:request) do
49
+ { user_keys: '',
50
+ pac_provider: pac_provider,
51
+ biller: biller,
52
+ bill: bill }
53
+ end
54
+
55
+ context 'has a nil value' do
56
+ before do
57
+ @response = subject.create_cfdi(request)
58
+ end
59
+
60
+ it 'returns an invalid status' do
61
+ expect(@response[:status]).to be_false
62
+ end
63
+
64
+ it 'returns an error message' do
65
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
66
+ end
67
+ end
68
+
69
+ context 'not exist in the request' do
70
+ before do
71
+ request.delete :user_keys
72
+ @response = subject.create_cfdi(request)
73
+ end
74
+
75
+ it 'returns an invalid status' do
76
+ expect(@response[:status]).to be_false
77
+ end
78
+
79
+ it 'returns an error message' do
80
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
81
+ end
82
+ end
83
+ end
84
+
85
+ context 'and pac provider' do
86
+ let(:request) do
87
+ { user_keys: user_keys,
88
+ pac_provider: '',
89
+ biller: biller,
90
+ bill: bill }
91
+ end
92
+
93
+ context 'has a nil value' do
94
+ before do
95
+ @response = subject.create_cfdi(request)
96
+ end
97
+
98
+ it 'returns an invalid status' do
99
+ expect(@response[:status]).to be_false
100
+ end
101
+
102
+ it 'returns an error message' do
103
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
104
+ end
105
+ end
106
+
107
+ context 'not exist in the request' do
108
+ before do
109
+ request.delete :pac_provider
110
+ @response = subject.create_cfdi(request)
111
+ end
112
+
113
+ it 'returns an invalid status' do
114
+ expect(@response[:status]).to be_false
115
+ end
116
+
117
+ it 'returns an error message' do
118
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+ context 'and biller' do
125
+ let(:request) do
126
+ { user_keys: user_keys,
127
+ pac_provider: pac_provider,
128
+ biller: '',
129
+ bill: bill }
130
+ end
131
+
132
+ context 'has a nil value' do
133
+ before do
134
+ @response = subject.create_cfdi(request)
135
+ end
136
+
137
+ it 'returns an invalid status' do
138
+ expect(@response[:status]).to be_false
139
+ end
140
+
141
+ it 'returns an error message' do
142
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
143
+ end
144
+ end
145
+
146
+ context 'not exist in the request' do
147
+ before do
148
+ request.delete :biller
149
+ @response = subject.create_cfdi(request)
150
+ end
151
+
152
+ it 'returns an invalid status' do
153
+ expect(@response[:status]).to be_false
154
+ end
155
+
156
+ it 'returns an error message' do
157
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ context 'and bill' do
164
+ let(:request) do
165
+ { user_keys: user_keys,
166
+ pac_provider: pac_provider,
167
+ biller: biller,
168
+ bill: '' }
169
+ end
170
+
171
+ context 'has a nil value' do
172
+ before do
173
+ @response = subject.create_cfdi(request)
174
+ end
175
+
176
+ it 'returns an invalid status' do
177
+ expect(@response[:status]).to be_false
178
+ end
179
+
180
+ it 'returns an error message' do
181
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
182
+ end
183
+ end
184
+
185
+ context 'not exist in the request' do
186
+ before do
187
+ request.delete :bill
188
+ @response = subject.create_cfdi(request)
189
+ end
190
+
191
+ it 'returns an invalid status' do
192
+ expect(@response[:status]).to be_false
193
+ end
194
+
195
+ it 'returns an error message' do
196
+ expect(@response[:error_msg]).to eql('Parametros invalidos')
197
+ end
198
+ end
199
+
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,43 @@
1
+ require 'services/pac_provider_fm'
2
+ require 'bill_xml_request'
3
+ require 'fixtures/bill_example'
4
+
5
+ describe PacProviderFM do
6
+ let(:user_keys) do
7
+ { id: 'UsuarioPruebasWS',
8
+ password: 'b9ec2afa3361a59af4b4d102d3f704eabdf097d4',
9
+ namespace: 'https://t2demo.facturacionmoderna.com/timbrado/soap',
10
+ endpoint: 'https://t2demo.facturacionmoderna.com/timbrado/soap',
11
+ wsdl: 'https://t2demo.facturacionmoderna.com/timbrado/wsdl',
12
+ log: false,
13
+ ssl_verify_mode: :none
14
+ }
15
+ end
16
+ let(:biller) do
17
+ {
18
+ certificate: File.open('./spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.cer'),
19
+ key: File.open('spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key.pem'),
20
+ password: '12345678a'
21
+ }
22
+ end
23
+ let(:bill) do
24
+ BillExample.request
25
+ end
26
+ let(:xml_file) do
27
+ BillXmlRequest.new_xml(biller, bill).generate_xml_request
28
+ end
29
+
30
+ subject{ PacProviderFM.new xml_file }
31
+
32
+ describe '#rining' do
33
+ context 'When requesting a valid xml file with valid user keys' do
34
+ before do
35
+ @response = subject.rining(user_keys)
36
+ end
37
+
38
+ specify do
39
+ expect(@response[:status]).to be_true
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,14 @@
1
+ require 'services/pac_provider_service'
2
+
3
+ describe PacProviderService do
4
+ let(:xml_file) do
5
+ xml = File.open './spec/docs_examples/base_xml_file.xml'
6
+ xml.read
7
+ end
8
+ subject{ PacProviderService.new xml_file }
9
+ describe '#tax_receipt_xml' do
10
+ specify do
11
+ expect(subject.tax_receipt_xml).to include('cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3')
12
+ end
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: facturacion_electronica
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ulices Barajas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cfdi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fm_timbrado_cfdi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Processing electronic invoices and ring through a PAC
84
+ email:
85
+ - ulices.barajas@crowdint.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - facturacion_electronica.gemspec
96
+ - lib/bill_xml_request.rb
97
+ - lib/facturacion_electronica.rb
98
+ - lib/facturacion_electronica/version.rb
99
+ - lib/services/pac_provider_fm.rb
100
+ - lib/services/pac_provider_service.rb
101
+ - spec/docs_examples/CertificadosDemo-FM/ESI920427886/contrasen~a.txt
102
+ - spec/docs_examples/CertificadosDemo-FM/ESI920427886/esi920427886_1210221507s.cer
103
+ - spec/docs_examples/CertificadosDemo-FM/ESI920427886/esi920427886_1210221507s.key
104
+ - spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/TUEM470405V4A_1210231509S.cer
105
+ - spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/TUEM470405V4A_1210231509S.key
106
+ - spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/contrasen~a.txt
107
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.cer
108
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key
109
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key.pem
110
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/contrasen~a.txt
111
+ - spec/docs_examples/base_xml_file.xml
112
+ - spec/fixtures/bill_example.rb
113
+ - spec/lib/bill_xml_request_spec.rb
114
+ - spec/lib/facturacion_electronica_spec.rb
115
+ - spec/lib/services/pac_provider_fm_spec.rb
116
+ - spec/lib/services/pac_provider_service_spec.rb
117
+ homepage: ''
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.0.3
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Processing electronic invoices and ring through a PAC
141
+ test_files:
142
+ - spec/docs_examples/CertificadosDemo-FM/ESI920427886/contrasen~a.txt
143
+ - spec/docs_examples/CertificadosDemo-FM/ESI920427886/esi920427886_1210221507s.cer
144
+ - spec/docs_examples/CertificadosDemo-FM/ESI920427886/esi920427886_1210221507s.key
145
+ - spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/TUEM470405V4A_1210231509S.cer
146
+ - spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/TUEM470405V4A_1210231509S.key
147
+ - spec/docs_examples/CertificadosDemo-FM/TUEM470405V4A/contrasen~a.txt
148
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.cer
149
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key
150
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/TUMG620310R95_1210241209S.key.pem
151
+ - spec/docs_examples/CertificadosDemo-FM/TUMG620310R95/contrasen~a.txt
152
+ - spec/docs_examples/base_xml_file.xml
153
+ - spec/fixtures/bill_example.rb
154
+ - spec/lib/bill_xml_request_spec.rb
155
+ - spec/lib/facturacion_electronica_spec.rb
156
+ - spec/lib/services/pac_provider_fm_spec.rb
157
+ - spec/lib/services/pac_provider_service_spec.rb