afipws 1.0.4 → 1.1.0

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