afipws 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +102 -0
- data/.travis.yml +1 -0
- data/Gemfile.lock +22 -4
- data/LICENSE.txt +22 -0
- data/README.md +11 -5
- data/afipws.gemspec +1 -0
- data/lib/afipws.rb +2 -0
- data/lib/afipws/client.rb +4 -17
- data/lib/afipws/core_ext/hash.rb +2 -2
- data/lib/afipws/excepciones.rb +1 -1
- data/lib/afipws/type_conversions.rb +19 -16
- data/lib/afipws/version.rb +1 -1
- data/lib/afipws/ws_base.rb +12 -0
- data/lib/afipws/ws_constancia_inscripcion.rb +33 -0
- data/lib/afipws/wsaa.rb +9 -13
- data/lib/afipws/{wsfev1.wsdl → wsdl/wsfev1.wsdl} +1371 -1371
- data/lib/afipws/wsfe.rb +57 -38
- data/spec/afipws/core_ext/hash_spec.rb +6 -6
- data/spec/afipws/type_conversions_spec.rb +11 -12
- data/spec/afipws/ws_constancia_inscripcion_spec.rb +65 -0
- data/spec/afipws/wsaa_spec.rb +66 -58
- data/spec/afipws/wsfe_spec.rb +272 -259
- data/spec/fixtures/constancia_inscripcion_dummy/success.xml +11 -0
- data/spec/fixtures/constancia_inscripcion_get_persona/failure.xml +35 -0
- data/spec/fixtures/constancia_inscripcion_get_persona/success.xml +53 -0
- data/spec/fixtures/ws_constancia_inscripcion.wsdl +230 -0
- metadata +31 -5
- data/.autotest +0 -2
- data/autotest/discover.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9efcd1dff92381947ee6cb51d967b29be89807e7
|
4
|
+
data.tar.gz: a2d8e8b7887810180b2a1519acf28ccf9b03fc43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a27824e48e8e96b4f9924d6a106500da58e1d334a464e9dbd09c324c99c590b42f9d60a4fc596537cf6d75b2642ea9777a17f328a212d2f8e5aecb9162ae5301
|
7
|
+
data.tar.gz: b338ff05f6648220a3afbe577aad62b4fae07207d1ab941785774b730e3e3a58d59fab4e17f11f005877e6b452ae1a8545d5ac19e5a36af0597fdd10b995a94e
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
Style/Documentation:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
Style/MethodDefParentheses:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Style/ParallelAssignment:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Style/FrozenStringLiteralComment:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/FormatStringToken:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/EmptyMethod:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Style/GuardClause:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/CommentAnnotation:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/AsciiComments:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/StabbyLambdaParentheses:
|
29
|
+
EnforcedStyle: require_no_parentheses
|
30
|
+
|
31
|
+
Style/MultilineIfModifier:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/SafeNavigation:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/FormatString:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/AndOr:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/Next:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/NumericPredicate:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/SymbolArray:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Style/MutableConstant:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Style/RescueModifier:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Layout/SpaceInsideHashLiteralBraces:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Layout/MultilineMethodCallIndentation:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Layout/TrailingBlankLines:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Layout/IndentArray:
|
68
|
+
EnforcedStyle: consistent
|
69
|
+
|
70
|
+
Layout/AlignParameters:
|
71
|
+
EnforcedStyle: with_fixed_indentation
|
72
|
+
|
73
|
+
Layout/SpaceInLambdaLiteral:
|
74
|
+
Enabled: false
|
75
|
+
|
76
|
+
Metrics:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
Bundler:
|
80
|
+
Enabled: false
|
81
|
+
|
82
|
+
Lint/Void:
|
83
|
+
Exclude:
|
84
|
+
- spec/**/*.rb
|
85
|
+
|
86
|
+
Lint/AssignmentInCondition:
|
87
|
+
Enabled: false
|
88
|
+
|
89
|
+
Lint/ShadowingOuterLocalVariable:
|
90
|
+
Enabled: false
|
91
|
+
|
92
|
+
Lint/AmbiguousRegexpLiteral:
|
93
|
+
Enabled: false
|
94
|
+
|
95
|
+
Lint/AmbiguousOperator:
|
96
|
+
Enabled: false
|
97
|
+
|
98
|
+
Lint/AmbiguousBlockAssociation:
|
99
|
+
Enabled: false
|
100
|
+
|
101
|
+
Naming/UncommunicativeMethodParamName:
|
102
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
afipws (1.0.
|
4
|
+
afipws (1.0.4)
|
5
5
|
activesupport
|
6
6
|
builder
|
7
7
|
nokogiri
|
@@ -18,6 +18,7 @@ GEM
|
|
18
18
|
akami (1.3.1)
|
19
19
|
gyoku (>= 0.4.0)
|
20
20
|
nokogiri
|
21
|
+
ast (2.4.0)
|
21
22
|
builder (3.2.3)
|
22
23
|
coderay (1.1.2)
|
23
24
|
concurrent-ruby (1.0.5)
|
@@ -45,6 +46,7 @@ GEM
|
|
45
46
|
socksify
|
46
47
|
i18n (1.0.1)
|
47
48
|
concurrent-ruby (~> 1.0)
|
49
|
+
jaro_winkler (1.5.1)
|
48
50
|
listen (3.1.5)
|
49
51
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
50
52
|
rb-inotify (~> 0.9, >= 0.9.7)
|
@@ -62,11 +64,16 @@ GEM
|
|
62
64
|
notiffany (0.1.1)
|
63
65
|
nenv (~> 0.1)
|
64
66
|
shellany (~> 0.0)
|
67
|
+
parallel (1.12.1)
|
68
|
+
parser (2.5.3.0)
|
69
|
+
ast (~> 2.4.0)
|
70
|
+
powerpack (0.1.2)
|
65
71
|
pry (0.11.3)
|
66
72
|
coderay (~> 1.1.0)
|
67
73
|
method_source (~> 0.9.0)
|
68
|
-
rack (2.0.
|
69
|
-
|
74
|
+
rack (2.0.6)
|
75
|
+
rainbow (3.0.0)
|
76
|
+
rake (12.3.2)
|
70
77
|
rb-fsevent (0.10.3)
|
71
78
|
rb-inotify (0.9.10)
|
72
79
|
ffi (>= 0.5.0, < 2)
|
@@ -83,6 +90,15 @@ GEM
|
|
83
90
|
diff-lcs (>= 1.2.0, < 2.0)
|
84
91
|
rspec-support (~> 3.7.0)
|
85
92
|
rspec-support (3.7.1)
|
93
|
+
rubocop (0.61.1)
|
94
|
+
jaro_winkler (~> 1.5.1)
|
95
|
+
parallel (~> 1.10)
|
96
|
+
parser (>= 2.5, != 2.5.1.1)
|
97
|
+
powerpack (~> 0.1)
|
98
|
+
rainbow (>= 2.2.2, < 4.0)
|
99
|
+
ruby-progressbar (~> 1.7)
|
100
|
+
unicode-display_width (~> 1.4.0)
|
101
|
+
ruby-progressbar (1.10.0)
|
86
102
|
ruby_dep (1.5.0)
|
87
103
|
savon (2.11.2)
|
88
104
|
akami (~> 1.2)
|
@@ -98,6 +114,7 @@ GEM
|
|
98
114
|
thread_safe (0.3.6)
|
99
115
|
tzinfo (1.2.5)
|
100
116
|
thread_safe (~> 0.1)
|
117
|
+
unicode-display_width (1.4.0)
|
101
118
|
wasabi (3.5.0)
|
102
119
|
httpi (~> 2.0)
|
103
120
|
nokogiri (>= 1.4.2)
|
@@ -111,6 +128,7 @@ DEPENDENCIES
|
|
111
128
|
mocha
|
112
129
|
rake
|
113
130
|
rspec
|
131
|
+
rubocop
|
114
132
|
|
115
133
|
BUNDLED WITH
|
116
|
-
1.16.
|
134
|
+
1.16.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2011 Emmanuel Nicolau
|
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
CHANGED
@@ -4,13 +4,19 @@ Ruby client para los web services de la AFIP.
|
|
4
4
|
|
5
5
|
[![Build Status](https://travis-ci.org/eeng/afipws.svg?branch=master)](https://travis-ci.org/eeng/afipws)
|
6
6
|
|
7
|
+
## Servicios Disponibles
|
8
|
+
|
9
|
+
* WSAA
|
10
|
+
* WSFE
|
11
|
+
* WSConstanciaInscripcion (ws_sr_constancia_inscripcion)
|
12
|
+
|
7
13
|
## Uso
|
8
14
|
|
9
15
|
Primero hay que crear la clave privada y obtener el certificado correspondiente según los pasos indicados [aquí](http://www.afip.gov.ar/ws/WSAA/cert-req-howto.txt).
|
10
16
|
|
11
17
|
Luego hay que instalar la librería:
|
12
18
|
|
13
|
-
```
|
19
|
+
```
|
14
20
|
gem install afipws
|
15
21
|
```
|
16
22
|
|
@@ -22,13 +28,13 @@ ws = Afipws::WSFE.new env: :development, cuit: '...', key: File.read('test.key')
|
|
22
28
|
puts ws.cotizacion 'DOL'
|
23
29
|
```
|
24
30
|
|
25
|
-
De momento sólo están soportados los servicios WSAA y WSFEv1.
|
26
31
|
Ver specs para más ejemplos.
|
27
32
|
|
28
33
|
## Contributing
|
29
34
|
|
30
35
|
1. Fork it
|
31
36
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
-
3.
|
33
|
-
4.
|
34
|
-
5.
|
37
|
+
3. Test, test, test (`guard`)
|
38
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
39
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
40
|
+
6. Create new Pull Request
|
data/afipws.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_development_dependency 'rake'
|
23
23
|
s.add_development_dependency 'mocha'
|
24
24
|
s.add_development_dependency 'guard-rspec'
|
25
|
+
s.add_development_dependency 'rubocop'
|
25
26
|
s.add_dependency "builder"
|
26
27
|
s.add_dependency "savon", '~> 2.11.0'
|
27
28
|
s.add_dependency "nokogiri"
|
data/lib/afipws.rb
CHANGED
data/lib/afipws/client.rb
CHANGED
@@ -1,28 +1,15 @@
|
|
1
1
|
module Afipws
|
2
2
|
class Client
|
3
3
|
def initialize savon_options
|
4
|
-
@client = Savon.client savon_options.reverse_merge(soap_version: 2)
|
4
|
+
@client = Savon.client savon_options.reverse_merge(soap_version: 2, ssl_version: :TLSv1)
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def request action, body = nil
|
8
|
-
response = raw_request(action, body).to_hash[:"#{action}_response"][:"#{action}_result"]
|
9
|
-
if response[:errors]
|
10
|
-
raise WSError, Array.wrap(response[:errors][:err])
|
11
|
-
else
|
12
|
-
response
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def raw_request action, body = nil
|
17
8
|
@client.call action, message: body
|
18
9
|
end
|
19
|
-
|
10
|
+
|
20
11
|
def operations
|
21
12
|
@client.operations
|
22
13
|
end
|
23
|
-
|
24
|
-
def method_missing method_sym, *args
|
25
|
-
request method_sym, *args
|
26
|
-
end
|
27
14
|
end
|
28
|
-
end
|
15
|
+
end
|
data/lib/afipws/core_ext/hash.rb
CHANGED
data/lib/afipws/excepciones.rb
CHANGED
@@ -7,33 +7,36 @@ module Afipws
|
|
7
7
|
def x2r x, types
|
8
8
|
convert x, types, parsing_fn
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
private
|
12
|
+
|
12
13
|
# Hace una conversión recursiva de tipo de todos los values según los tipos de las keys indicados en types
|
13
14
|
def convert object, types, convert_fn
|
14
15
|
case object
|
15
|
-
when Array then
|
16
|
+
when Array then
|
16
17
|
object.map { |e| convert e, types, convert_fn }
|
17
|
-
when Hash then
|
18
|
-
Hash[object.map
|
19
|
-
|
18
|
+
when Hash then
|
19
|
+
Hash[object.map do |k, v|
|
20
|
+
[k, v.is_a?(Hash) || v.is_a?(Array) ? convert(v, types, convert_fn) : convert_fn[types[k]].call(v)]
|
21
|
+
end]
|
22
|
+
else
|
20
23
|
object
|
21
24
|
end
|
22
25
|
end
|
23
|
-
|
26
|
+
|
24
27
|
def parsing_fn
|
25
|
-
@
|
26
|
-
p[:date] =
|
27
|
-
p[:integer] =
|
28
|
-
p[:float] =
|
29
|
-
p[:boolean] =
|
28
|
+
@parsing_fn ||= Hash.new(proc { |v| v }).tap { |p|
|
29
|
+
p[:date] = proc { |v| ::Date.parse(v) rescue nil }
|
30
|
+
p[:integer] = proc { |v| v.to_i }
|
31
|
+
p[:float] = proc { |v| v.to_f }
|
32
|
+
p[:boolean] = proc { |v| v == 'S' }
|
30
33
|
}
|
31
34
|
end
|
32
35
|
|
33
36
|
def marshall_fn
|
34
|
-
@
|
35
|
-
p[:date] =
|
36
|
-
|
37
|
-
end
|
37
|
+
@marshall_fn ||= Hash.new(proc { |other| other }).tap do |p|
|
38
|
+
p[:date] = proc { |date| date.strftime('%Y%m%d') }
|
39
|
+
end
|
40
|
+
end
|
38
41
|
end
|
39
|
-
end
|
42
|
+
end
|
data/lib/afipws/version.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Afipws
|
2
|
+
class WSConstanciaInscripcion < WSBase
|
3
|
+
WSDL = {
|
4
|
+
development: 'https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL',
|
5
|
+
production: 'https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL',
|
6
|
+
test: Root + '/spec/fixtures/ws_constancia_inscripcion.wsdl'
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
def initialize options = {}
|
10
|
+
super
|
11
|
+
@wsaa = WSAA.new options.merge(service: 'ws_sr_constancia_inscripcion')
|
12
|
+
@client = Client.new Hash(options[:savon]).reverse_merge(wsdl: WSDL[env], soap_version: 1)
|
13
|
+
end
|
14
|
+
|
15
|
+
def dummy
|
16
|
+
request(:dummy)[:return]
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_persona id
|
20
|
+
request(:get_persona, auth.merge(id_persona: id))[:persona_return]
|
21
|
+
end
|
22
|
+
|
23
|
+
def auth
|
24
|
+
wsaa.auth.merge(cuit_representada: cuit)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def request action, body = nil
|
30
|
+
@client.request(action, body).to_hash[:"#{action}_response"]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/afipws/wsaa.rb
CHANGED
@@ -3,9 +3,9 @@ module Afipws
|
|
3
3
|
attr_reader :key, :cert, :service, :ta, :cuit, :client
|
4
4
|
|
5
5
|
WSDL = {
|
6
|
-
development:
|
7
|
-
production:
|
8
|
-
test: Root +
|
6
|
+
development: 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl',
|
7
|
+
production: 'https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl',
|
8
|
+
test: Root + '/spec/fixtures/wsaa.wsdl'
|
9
9
|
}
|
10
10
|
|
11
11
|
def initialize options = {}
|
@@ -35,7 +35,7 @@ module Afipws
|
|
35
35
|
def firmar_tra tra, key, crt
|
36
36
|
key = OpenSSL::PKey::RSA.new key
|
37
37
|
crt = OpenSSL::X509::Certificate.new crt
|
38
|
-
OpenSSL::PKCS7
|
38
|
+
OpenSSL::PKCS7.sign crt, key, tra
|
39
39
|
end
|
40
40
|
|
41
41
|
def codificar_tra pkcs7
|
@@ -47,7 +47,7 @@ module Afipws
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def login
|
50
|
-
response = @client.
|
50
|
+
response = @client.request :login_cms, in0: tra(@key, @cert, @service, @ttl)
|
51
51
|
ta = Nokogiri::XML(Nokogiri::XML(response.to_xml).text)
|
52
52
|
{
|
53
53
|
token: ta.css('token').text,
|
@@ -59,10 +59,9 @@ module Afipws
|
|
59
59
|
raise WSError, f.message
|
60
60
|
end
|
61
61
|
|
62
|
-
# Obtiene un TA, lo cachea hasta que expire, y devuelve el hash Auth listo para pasarle al Client en los otros WS
|
63
62
|
def auth
|
64
63
|
ta = obtener_y_cachear_ta
|
65
|
-
{
|
64
|
+
{token: ta[:token], sign: ta[:sign]}
|
66
65
|
end
|
67
66
|
|
68
67
|
private
|
@@ -90,15 +89,12 @@ module Afipws
|
|
90
89
|
end
|
91
90
|
|
92
91
|
def restore_ta
|
93
|
-
Marshal.load(File.read(@ta_path)) if File.
|
92
|
+
Marshal.load(File.read(@ta_path)) if File.exist?(@ta_path)
|
94
93
|
end
|
95
94
|
|
96
95
|
def persist_ta ta
|
97
|
-
|
98
|
-
|
99
|
-
FileUtils.mkdir_p(dirname)
|
100
|
-
end
|
101
|
-
File.open(@ta_path, "wb") { |f| f.write(Marshal.dump(ta)) }
|
96
|
+
FileUtils.mkdir_p(File.dirname(@ta_path))
|
97
|
+
File.open(@ta_path, 'wb') { |f| f.write(Marshal.dump(ta)) }
|
102
98
|
end
|
103
99
|
end
|
104
100
|
end
|