afipws 1.0.4 → 1.1.0

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: 9efcd1dff92381947ee6cb51d967b29be89807e7
4
- data.tar.gz: a2d8e8b7887810180b2a1519acf28ccf9b03fc43
3
+ metadata.gz: 5ed8e558f8cf41675bf7ba19aa0f8c0b6cc29bb5
4
+ data.tar.gz: 271002cc672721b11bce0c1824c011d518a264f4
5
5
  SHA512:
6
- metadata.gz: a27824e48e8e96b4f9924d6a106500da58e1d334a464e9dbd09c324c99c590b42f9d60a4fc596537cf6d75b2642ea9777a17f328a212d2f8e5aecb9162ae5301
7
- data.tar.gz: b338ff05f6648220a3afbe577aad62b4fae07207d1ab941785774b730e3e3a58d59fab4e17f11f005877e6b452ae1a8545d5ac19e5a36af0597fdd10b995a94e
6
+ metadata.gz: 30ab4619718e0cd10b36d895868b8557a5b6a42b8463e66f61ba6ef1d2af6a7c18c8fc99fba06332db96ea2e2c88391bcd405df6417301c25b3e3c3ad9fec827
7
+ data.tar.gz: 13d842061c17115fe92fe8f14bcfd2df65240484ac95570178412b1d0a9d7ad8f77fa4272df83bb092e936bfcecadc1dbdc6ea3714f9aabf879dfecddccd99cc
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- afipws (1.0.4)
4
+ afipws (1.1.0)
5
5
  activesupport
6
6
  builder
7
7
  nokogiri
@@ -73,7 +73,7 @@ GEM
73
73
  method_source (~> 0.9.0)
74
74
  rack (2.0.6)
75
75
  rainbow (3.0.0)
76
- rake (12.3.2)
76
+ rake (10.4.2)
77
77
  rb-fsevent (0.10.3)
78
78
  rb-inotify (0.9.10)
79
79
  ffi (>= 0.5.0, < 2)
@@ -126,7 +126,7 @@ DEPENDENCIES
126
126
  afipws!
127
127
  guard-rspec
128
128
  mocha
129
- rake
129
+ pry
130
130
  rspec
131
131
  rubocop
132
132
 
data/README.md CHANGED
@@ -6,9 +6,11 @@ Ruby client para los web services de la AFIP.
6
6
 
7
7
  ## Servicios Disponibles
8
8
 
9
- * WSAA
10
- * WSFE
11
- * WSConstanciaInscripcion (ws_sr_constancia_inscripcion)
9
+ * wsaa (WSAA)
10
+ * wsfe (WSFE)
11
+ * ws_sr_constancia_inscripcion (WSConstanciaInscripcion)
12
+ * ws_sr_padron_a100 (PersonaServiceA100)
13
+ * ws_sr_padron_a4 (PersonaServiceA4)
12
14
 
13
15
  ## Uso
14
16
 
@@ -19,10 +19,10 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_development_dependency 'rspec'
22
- s.add_development_dependency 'rake'
23
22
  s.add_development_dependency 'mocha'
24
23
  s.add_development_dependency 'guard-rspec'
25
24
  s.add_development_dependency 'rubocop'
25
+ s.add_development_dependency 'pry'
26
26
  s.add_dependency "builder"
27
27
  s.add_dependency "savon", '~> 2.11.0'
28
28
  s.add_dependency "nokogiri"
@@ -17,3 +17,5 @@ require 'afipws/ws_base'
17
17
  require 'afipws/wsaa'
18
18
  require 'afipws/wsfe'
19
19
  require 'afipws/ws_constancia_inscripcion'
20
+ require 'afipws/persona_service_a4'
21
+ require 'afipws/persona_service_a100'
@@ -4,6 +4,7 @@ module Afipws
4
4
  @client = Savon.client savon_options.reverse_merge(soap_version: 2, ssl_version: :TLSv1)
5
5
  end
6
6
 
7
+
7
8
  def request action, body = nil
8
9
  @client.call action, message: body
9
10
  end
@@ -0,0 +1,43 @@
1
+ module Afipws
2
+ class PersonaServiceA100 < WSBase
3
+ WSDL = {
4
+ development: 'https://awshomo.afip.gov.ar/sr-parametros/webservices/parameterServiceA100?WSDL',
5
+ production: 'https://aws.afip.gov.ar/sr-parametros/webservices/parameterServiceA100?WSDL',
6
+ test: Root + '/spec/fixtures/ws_sr_padron_a100.wsdl'
7
+ }.freeze
8
+
9
+ def initialize options = {}
10
+ super
11
+ @wsaa = WSAA.new options.merge(service: 'ws_sr_padron_a100')
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 jurisdictions
20
+ get_parameter_collection_by_name 'SUPA.E_PROVINCIA'
21
+ end
22
+
23
+ def company_types
24
+ get_parameter_collection_by_name 'SUPA.TIPO_EMPRESA_JURIDICA'
25
+ end
26
+
27
+ def public_organisms
28
+ get_parameter_collection_by_name 'SUPA.E_ORGANISMO_INFORMANTE'
29
+ end
30
+
31
+ private
32
+
33
+ def get_parameter_collection_by_name type
34
+ message = {
35
+ token: auth[:token],
36
+ sign: auth[:sign],
37
+ cuitRepresentada: cuit,
38
+ collectionName: type
39
+ }
40
+ request(:get_parameter_collection_by_name, message)[:parameter_collection_return][:parameter_collection]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ module Afipws
2
+ class PersonaServiceA4 < WSBase
3
+ WSDL = {
4
+ development: 'https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA4?WSDL',
5
+ production: 'https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA4?WSDL',
6
+ test: Root + '/spec/fixtures/ws_sr_padron_a4.wsdl'
7
+ }.freeze
8
+
9
+ def initialize options = {}
10
+ super
11
+ @wsaa = WSAA.new options.merge(service: 'ws_sr_padron_a4')
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
+ message = auth.merge(cuitRepresentada: cuit, idPersona: id)
21
+ request(:get_persona, message)[:persona_return][:persona]
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Afipws
2
- VERSION = '1.0.4'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -3,10 +3,16 @@ module Afipws
3
3
  extend Forwardable
4
4
 
5
5
  attr_reader :wsaa, :client, :env
6
- def_delegators :wsaa, :cuit
6
+ def_delegators :wsaa, :cuit, :auth
7
7
 
8
8
  def initialize options = {}
9
9
  @env = (options[:env] || :test).to_sym
10
10
  end
11
+
12
+ def request action, body = nil
13
+ @client.request(action, body).to_hash[:"#{action}_response"]
14
+ rescue Savon::SOAPFault => f
15
+ raise WSError, f.message
16
+ end
11
17
  end
12
18
  end
@@ -17,17 +17,8 @@ module Afipws
17
17
  end
18
18
 
19
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"]
20
+ message = auth.merge(cuit_representada: cuit, id_persona: id)
21
+ request(:get_persona, message)[:persona_return]
31
22
  end
32
23
  end
33
24
  end
@@ -16,7 +16,7 @@ module Afipws
16
16
  @ttl = options[:ttl] || 2400
17
17
  @cuit = options[:cuit]
18
18
  @client = Client.new Hash(options[:savon]).reverse_merge(wsdl: WSDL[@env])
19
- @ta_path = File.join(Dir.pwd, 'tmp', "#{@cuit}-#{@env}-ta.dump")
19
+ @ta_path = File.join(Dir.pwd, 'tmp', "#{@cuit}-#{@env}-#{@service}-ta.dump")
20
20
  end
21
21
 
22
22
  def generar_tra service, ttl
@@ -4,8 +4,7 @@ module Afipws
4
4
 
5
5
  WSDL = {
6
6
  development: 'https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL',
7
- # production: 'https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL',
8
- production: Root + '/lib/afipws/wsdl/wsfev1.wsdl',
7
+ production: 'https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL',
9
8
  test: Root + '/spec/fixtures/wsfe.wsdl'
10
9
  }.freeze
11
10
 
@@ -24,11 +23,21 @@ module Afipws
24
23
  x2r get_array(r, :cbte_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
25
24
  end
26
25
 
26
+ def tipos_opcional
27
+ r = request :fe_param_get_tipos_opcional, auth
28
+ x2r get_array(r, :tipos_opcional), id: :integer, fch_desde: :date, fch_hasta: :date
29
+ end
30
+
27
31
  def tipos_documentos
28
32
  r = request :fe_param_get_tipos_doc, auth
29
33
  x2r get_array(r, :doc_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
30
34
  end
31
35
 
36
+ def tipos_concepto
37
+ r = request :fe_param_get_tipos_concepto, auth
38
+ x2r get_array(r, :concepto_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
39
+ end
40
+
32
41
  def tipos_monedas
33
42
  r = request :fe_param_get_tipos_monedas, auth
34
43
  x2r get_array(r, :moneda), fch_desde: :date, fch_hasta: :date
@@ -63,12 +72,13 @@ module Afipws
63
72
  }
64
73
  }
65
74
  }
66
- r = request :fecae_solicitar, auth.merge(r2x(mensaje, cbte_fch: :date))
75
+ mensaje = r2x(mensaje, cbte_fch: :date, fch_serv_desde: :date, fch_serv_hasta: :date, fch_vto_pago: :date)
76
+ r = request :fecae_solicitar, auth.merge(mensaje)
67
77
  r = Array.wrap(r[:fe_det_resp][:fecae_det_response]).map do |h|
68
78
  obs = Array.wrap(h[:observaciones] ? h[:observaciones][:obs] : nil)
69
79
  h.select_keys(:cae, :cae_fch_vto, :resultado).merge(cbte_nro: h[:cbte_desde], observaciones: obs)
70
80
  end
71
- x2r r, cae_fch_vto: :date, cbte_nro: :integer, code: :integer
81
+ x2r r, cae_fch_vto: :date, fch_serv_desde: :date, fch_serv_hasta: :date, fch_vto_pago: :date, cbte_nro: :integer, code: :integer
72
82
  end
73
83
 
74
84
  def comprobante_to_request comprobante
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ module Afipws
4
+ describe PersonaServiceA100 do
5
+ let(:ta) { {token: 't', sign: 's'} }
6
+ let(:ws) { PersonaServiceA100.new(cuit: '12345678912').tap { |ws| ws.wsaa.stubs auth: ta } }
7
+ let(:message) { ta.merge cuitRepresentada: '12345678912' }
8
+
9
+ context 'métodos API' do
10
+ it 'dummy' do
11
+ savon.expects(:dummy).returns(fixture('ws_sr_padron_a100/dummy/success'))
12
+ ws.dummy.should == { appserver: 'OK', authserver: 'OK', dbserver: 'OK' }
13
+ end
14
+
15
+ it 'jurisdictions' do
16
+ savon.expects(:get_parameter_collection_by_name)
17
+ .with(message: message.merge(collectionName: 'SUPA.E_PROVINCIA'))
18
+ .returns(fixture('ws_sr_padron_a100/jurisdictions/success'))
19
+ ws.jurisdictions.should have_entries name: 'SUPA.E_PROVINCIA'
20
+ end
21
+
22
+ it 'company_types' do
23
+ savon.expects(:get_parameter_collection_by_name)
24
+ .with(message: message.merge(collectionName: 'SUPA.TIPO_EMPRESA_JURIDICA'))
25
+ .returns(fixture('ws_sr_padron_a100/company_types/success'))
26
+ ws.company_types.should have_entries name: 'SUPA.TIPO_EMPRESA_JURIDICA'
27
+ end
28
+
29
+ it 'public_organisms' do
30
+ savon.expects(:get_parameter_collection_by_name)
31
+ .with(message: message.merge(collectionName: 'SUPA.E_ORGANISMO_INFORMANTE'))
32
+ .returns(fixture('ws_sr_padron_a100/public_organisms/success'))
33
+ ws.public_organisms.should have_entries name: 'SUPA.E_ORGANISMO_INFORMANTE'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ module Afipws
4
+ describe PersonaServiceA4 do
5
+ let(:ta) { {token: 't', sign: 's'} }
6
+ let(:ws) { PersonaServiceA4.new(cuit: '12345678912').tap { |ws| ws.wsaa.stubs auth: ta } }
7
+ let(:message) { ta.merge cuitRepresentada: '12345678912' }
8
+
9
+ context 'métodos API' do
10
+ it 'dummy' do
11
+ savon.expects(:dummy).returns(fixture('ws_sr_padron_a4/dummy/success'))
12
+ ws.dummy.should == { appserver: 'OK', authserver: 'OK', dbserver: 'OK' }
13
+ end
14
+
15
+ it 'get_persona' do
16
+ savon.expects(:get_persona)
17
+ .with(message: message.merge(idPersona: '98765432198'))
18
+ .returns(fixture('ws_sr_padron_a4/get_persona/success'))
19
+ ws.get_persona('98765432198').should have_entries apellido: 'ERNESTO DANIEL'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -4,7 +4,7 @@ module Afipws
4
4
  describe WSConstanciaInscripcion do
5
5
  let(:ta) { {token: 't', sign: 's'} }
6
6
  let(:ws) { WSConstanciaInscripcion.new(cuit: '1').tap { |ws| ws.wsaa.stubs auth: ta } }
7
- let(:auth) { ta.merge(cuit_representada: '1') }
7
+ let(:message) { ta.merge cuit_representada: '1' }
8
8
 
9
9
  context 'métodos API' do
10
10
  it 'dummy' do
@@ -14,7 +14,7 @@ module Afipws
14
14
 
15
15
  it 'debería devolver un hash con los datos generales y regímenes impositivos' do
16
16
  savon.expects(:get_persona)
17
- .with(message: auth.merge(id_persona: '20294834487'))
17
+ .with(message: message.merge(id_persona: '20294834487'))
18
18
  .returns(fixture('constancia_inscripcion_get_persona/success'))
19
19
  r = ws.get_persona '20294834487'
20
20
  r[:datos_generales].should have_entries(
@@ -37,13 +37,22 @@ module Afipws
37
37
  end
38
38
 
39
39
  it 'cuando hay errores en la constancia sigue la misma lógica' do
40
- savon.expects(:get_persona).with(message: auth).returns(fixture('constancia_inscripcion_get_persona/failure'))
41
- r = ws.get_persona '20294834487'
40
+ savon.expects(:get_persona)
41
+ .with(message: message.merge(id_persona: '20294834489'))
42
+ .returns(fixture('constancia_inscripcion_get_persona/failure'))
43
+ r = ws.get_persona '20294834489'
42
44
  r[:error_regimen_general].should have_entries(
43
45
  error: 'El contribuyente cuenta con impuestos con baja de oficio por Decreto 1299/98',
44
46
  mensaje: 'No cumple con las condiciones para enviar datos del regimen general'
45
47
  )
46
48
  end
49
+
50
+ it 'cuando no existe la persona' do
51
+ savon.expects(:get_persona)
52
+ .with(message: message.merge(id_persona: '123'))
53
+ .returns(fixture('constancia_inscripcion_get_persona/fault'))
54
+ -> { ws.get_persona '123' }.should raise_error WSError, /No existe persona con ese Id/
55
+ end
47
56
  end
48
57
 
49
58
  context 'entorno' do
@@ -49,7 +49,7 @@ module Afipws
49
49
 
50
50
  context 'auth' do
51
51
  before do
52
- FileUtils.rm_rf Dir.glob('tmp/*ta.dump')
52
+ FileUtils.rm_rf Dir.glob('tmp/*-test-*-ta.dump')
53
53
  Time.stubs(:now).returns(Time.local(2010, 1, 1))
54
54
  end
55
55
 
@@ -25,6 +25,11 @@ module Afipws
25
25
  ws.tipos_documentos.should == [{ id: 80, desc: 'CUIT', fch_desde: Date.new(2008, 7, 25), fch_hasta: nil }]
26
26
  end
27
27
 
28
+ it 'tipos_concepto' do
29
+ savon.expects(:fe_param_get_tipos_concepto).with(message: auth).returns(fixture('fe_param_get_tipos_concepto/success'))
30
+ ws.tipos_concepto.should == [{ id: 1, desc: "Producto", fch_desde: Date.new(2008,7,25), fch_hasta: nil }]
31
+ end
32
+
28
33
  it 'tipos_monedas' do
29
34
  savon.expects(:fe_param_get_tipos_monedas).with(message: auth).returns(fixture('fe_param_get_tipos_monedas/success'))
30
35
  ws.tipos_monedas.should == [
@@ -33,6 +38,11 @@ module Afipws
33
38
  ]
34
39
  end
35
40
 
41
+ it 'tipos_opcional' do
42
+ savon.expects(:fe_param_get_tipos_opcional).with(message: auth).returns(fixture('fe_param_get_tipos_opcional/success'))
43
+ ws.tipos_opcional.should == []
44
+ end
45
+
36
46
  it 'tipos_iva' do
37
47
  savon.expects(:fe_param_get_tipos_iva).with(message: auth).returns(fixture('fe_param_get_tipos_iva/success'))
38
48
  ws.tipos_iva.should == [{ id: 5, desc: '21%', fch_desde: Date.new(2009, 2, 20), fch_hasta: nil }]
@@ -235,7 +245,7 @@ module Afipws
235
245
  end
236
246
 
237
247
  context 'autenticacion' do
238
- before { FileUtils.rm_rf Dir.glob('tmp/*ta.dump') }
248
+ before { FileUtils.rm_rf Dir.glob('tmp/*-test-*-ta.dump') }
239
249
 
240
250
  it 'debería autenticarse usando el WSAA' do
241
251
  wsfe = WSFE.new cuit: '1', cert: 'cert', key: 'key'
@@ -260,7 +270,7 @@ module Afipws
260
270
 
261
271
  it 'debería usar las url para production cuando el env es production' do
262
272
  Client.expects(:new).with(wsdl: 'https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl')
263
- Client.expects(:new).with(has_entries(wsdl: File.expand_path(__dir__ + '/../../') + '/lib/afipws/wsdl/wsfev1.wsdl'))
273
+ Client.expects(:new).with(wsdl: 'https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL', convert_request_keys_to: :camelcase)
264
274
  wsfe = WSFE.new env: 'production'
265
275
  wsfe.env.should == :production
266
276
  end
@@ -0,0 +1,8 @@
1
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
+ <soap:Body>
3
+ <soap:Fault>
4
+ <faultcode>soap:Server</faultcode>
5
+ <faultstring>No existe persona con ese Id</faultstring>
6
+ </soap:Fault>
7
+ </soap:Body>
8
+ </soap:Envelope>
@@ -0,0 +1,17 @@
1
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
2
+ <soap:Body>
3
+ <FEParamGetTiposConceptoResponse xmlns="http://ar.gov.afip.dif.FEV1/">
4
+ <FEParamGetTiposConceptoResult>
5
+ <ResultGet>
6
+ <ConceptoTipo>
7
+ <Id>1</Id>
8
+ <Desc>Producto</Desc>
9
+ <FchDesde>20080725</FchDesde>
10
+ <FchHasta>NULL</FchHasta>
11
+ </ConceptoTipo>
12
+ </ResultGet>
13
+ </FEParamGetTiposConceptoResult>
14
+ </FEParamGetTiposConceptoResponse>
15
+ </soap:Body>
16
+ </soap:Envelope>
17
+
@@ -0,0 +1,16 @@
1
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
2
+ <soap:Body>
3
+ <FEParamGetTiposOpcionalResponse xmlns="http://ar.gov.afip.dif.FEV1/">
4
+ <FEParamGetTiposOpcionalResult>
5
+ <ResultGet>
6
+ <OpcionalTipo>
7
+ <Id>1</Id>
8
+ <Desc>Producto</Desc>
9
+ <FchDesde>20080725</FchDesde>
10
+ <FchHasta>NULL</FchHasta>
11
+ </OpcionalTipo>
12
+ </ResultGet>
13
+ </FEParamGetTiposOpcionalResult>
14
+ </FEParamGetTiposOpcionalResponse>
15
+ </soap:Body>
16
+ </soap:Envelope>