facturacion_electronica 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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