Afip 1.4.7 → 1.4.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Afip-1.2.1.gem +0 -0
- data/Afip-1.4.gem +0 -0
- data/Afip.gemspec +41 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/Afip.rb +59 -0
- data/lib/Afip/auth_data.rb +71 -0
- data/lib/Afip/authorizer.rb +10 -0
- data/lib/Afip/bill.rb +274 -0
- data/lib/Afip/constants.rb +115 -0
- data/lib/Afip/core_ext/float.rb +8 -0
- data/lib/Afip/core_ext/hash.rb +23 -0
- data/lib/Afip/core_ext/string.rb +12 -0
- data/lib/Afip/ctg.rb +234 -0
- data/lib/Afip/padron.rb +184 -0
- data/lib/Afip/version.rb +3 -0
- data/lib/Afip/wsaa.rb +94 -0
- data/pkg/Afip-1.4.7.gem +0 -0
- metadata +25 -2
@@ -0,0 +1,115 @@
|
|
1
|
+
module Afip
|
2
|
+
CBTE_TIPO = {
|
3
|
+
"01"=>"Factura A",
|
4
|
+
"02"=>"Nota de Débito A",
|
5
|
+
"03"=>"Nota de Crédito A",
|
6
|
+
"06"=>"Factura B",
|
7
|
+
"07"=>"Nota de Debito B",
|
8
|
+
"08"=>"Nota de Credito B",
|
9
|
+
"11"=>"Factura C",
|
10
|
+
"12"=>"Nota de Debito C",
|
11
|
+
"13"=>"Nota de Credito C",
|
12
|
+
"201" => "Factura de Crédito electrónica MiPyMEs (FCE) A",
|
13
|
+
"202" => "Nota de Débito electrónica MiPyMEs (FCE) A",
|
14
|
+
"203" => "Nota de Crédito electrónica MiPyMEs (FCE) A",
|
15
|
+
"206" => "Factura de Crédito electrónica MiPyMEs (FCE) B",
|
16
|
+
"207" => "Nota de Débito electrónica MiPyMEs (FCE) B",
|
17
|
+
"208" => "Nota de Crédito electrónica MiPyMEs (FCE) B",
|
18
|
+
"211" => "Factura de Crédito electrónica MiPyMEs (FCE) C",
|
19
|
+
"212" => "Nota de Débito electrónica MiPyMEs (FCE) C",
|
20
|
+
"213" => "Nota de Crédito electrónica MiPyMEs (FCE) C",
|
21
|
+
}
|
22
|
+
|
23
|
+
OPCIONALES = [
|
24
|
+
{:id=>"2", :desc=>"RG Empresas Promovidas - Indentificador de proyecto vinculado a Régimen de Promoción Industrial"},
|
25
|
+
{:id=>"91", :desc=>"RG Bienes Usados 3411 - Nombre y Apellido o Denominación del vendedor del bien usado."},
|
26
|
+
{:id=>"92", :desc=>"RG Bienes Usados 3411 - Nacionalidad del vendedor del bien usado."},
|
27
|
+
{:id=>"93", :desc=>"RG Bienes Usados 3411 - Domicilio del vendedor del bien usado."},
|
28
|
+
{:id=>"5", :desc=>"Excepcion computo IVA Credito Fiscal"},
|
29
|
+
{:id=>"61", :desc=>"RG 3668 Impuesto al Valor Agregado - Art.12 IVA Firmante Doc Tipo"},
|
30
|
+
{:id=>"62", :desc=>"RG 3668 Impuesto al Valor Agregado - Art.12 IVA Firmante Doc Nro"},
|
31
|
+
{:id=>"7", :desc=>"RG 3668 Impuesto al Valor Agregado - Art.12 IVA Carácter del Firmante"},
|
32
|
+
{:id=>"10", :desc=>"RG 3.368 Establecimientos de educación pública de gestión privada - Actividad Comprendida"},
|
33
|
+
{:id=>"1011", :desc=>"RG 3.368 Establecimientos de educación pública de gestión privada - Tipo de Documento"},
|
34
|
+
{:id=>"1012", :desc=>"RG 3.368 Establecimientos de educación pública de gestión privada - Número de Documento"},
|
35
|
+
{:id=>"11", :desc=>"RG 2.820 Operaciones económicas vinculadas con bienes inmuebles - Actividad Comprendida"},
|
36
|
+
{:id=>"12", :desc=>"RG 3.687 Locación temporaria de inmuebles con fines turísticos - Actividad Comprendida"},
|
37
|
+
{:id=>"13", :desc=>"RG 2.863 Representantes de Modelos"},
|
38
|
+
{:id=>"14", :desc=>"RG 2.863 Agencias de publicidad"},
|
39
|
+
{:id=>"15", :desc=>"RG 2.863 Personas físicas que desarrollen actividad de modelaje"},
|
40
|
+
{:id=>"17", :desc=>"RG 4004-E Locación de inmuebles destino 'casa-habitación'. Dato 2 (dos) = facturación directa / Dato 1 (uno) = facturación a través de intermediario"},
|
41
|
+
{:id=>"1801", :desc=>"RG 4004-E Locación de inmuebles destino 'casa-habitación'. Clave Única de Identificación Tributaria (CUIT)."},
|
42
|
+
{:id=>"1802", :desc=>"RG 4004-E Locación de inmuebles destino 'casa-habitación'. Apellido y nombres, denominación y/o razón social."},
|
43
|
+
{:id=>"2101", :desc=>"Factura de Crédito Electrónica MiPyMEs (FCE) - CBU del Emisor"},
|
44
|
+
{:id=>"2102", :desc=>"Factura de Crédito Electrónica MiPyMEs (FCE) - Alias del Emisor"},
|
45
|
+
{:id=>"22", :desc=>"Factura de Crédito Electrónica MiPyMEs (FCE) - Anulación"},
|
46
|
+
{:id=>"23", :desc=>"Factura de Crédito Electrónica MiPyMEs (FCE) - Referencia Comercial"}
|
47
|
+
]
|
48
|
+
|
49
|
+
CONCEPTOS = {"Productos"=>"01", "Servicios"=>"02", "Productos y Servicios"=>"03"}
|
50
|
+
|
51
|
+
DOCUMENTOS = {"CUIT"=>"80", "CUIL"=>"86", "CDI"=>"87", "LE"=>"89", "LC"=>"90", "CI Extranjera"=>"91", "en tramite"=>"92", "Acta Nacimiento"=>"93", "CI Bs. As. RNP"=>"95", "DNI"=>"96", "Pasaporte"=>"94", "Doc. (Otro)"=>"99"}
|
52
|
+
|
53
|
+
MONEDAS = {
|
54
|
+
:peso => {:codigo => "PES", :nombre =>"Pesos Argentinos"},
|
55
|
+
:dolar => {:codigo => "DOL", :nombre =>"Dolar Estadounidense"},
|
56
|
+
:real => {:codigo => "012", :nombre =>"Real"},
|
57
|
+
:euro => {:codigo => "060", :nombre =>"Euro"},
|
58
|
+
:oro => {:codigo => "049", :nombre =>"Gramos de Oro Fino"}
|
59
|
+
}
|
60
|
+
|
61
|
+
ALIC_IVA = [["01", "No gravado"], ["02", "Exento"],["03", 0], ["04", 0.105], ["05", 0.21], ["06", 0.27]]
|
62
|
+
|
63
|
+
IVA_COND = ["Responsable Inscripto", "Responsable Monotributo"]
|
64
|
+
|
65
|
+
BILL_TYPE = {
|
66
|
+
:responsable_inscripto => {
|
67
|
+
:responsable_inscripto => "01",
|
68
|
+
:consumidor_final => "06",
|
69
|
+
:exento => "06",
|
70
|
+
:responsable_monotributo => "06",
|
71
|
+
:nota_credito_a => "03",
|
72
|
+
:nota_credito_b => "08",
|
73
|
+
:nota_debito_a => "02",
|
74
|
+
:nota_debito_b => "07"
|
75
|
+
},
|
76
|
+
:responsable_monotributo => {
|
77
|
+
:responsable_inscripto => "11",
|
78
|
+
:consumidor_final => "11",
|
79
|
+
:exento => "11",
|
80
|
+
:responsable_monotributo => "11",
|
81
|
+
:nota_credito_c => "13",
|
82
|
+
:nota_debito_c => "12"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
AVAILABLE_TYPES = {
|
87
|
+
:responsable_inscripto => {
|
88
|
+
:responsable_inscripto => ["01", "02", "03", "201", "202", "203"],
|
89
|
+
:consumidor_final => ["06", "07", "08", "206", "207", "208"],
|
90
|
+
:exento => ["06", "07", "08", "206", "207", "208"],
|
91
|
+
:responsable_monotributo => ["06", "07", "08", "206", "207", "208"],
|
92
|
+
},
|
93
|
+
:responsable_monotributo => {
|
94
|
+
:responsable_inscripto => ["11", "12", "13", "211", "212", "213"],
|
95
|
+
:consumidor_final => ["11", "12", "13", "211", "212", "213"],
|
96
|
+
:exento => ["11", "12", "13", "211", "212", "213"],
|
97
|
+
:responsable_monotributo => ["11", "12", "13", "211", "212", "213"]
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
URLS =
|
102
|
+
{
|
103
|
+
:test => {
|
104
|
+
:wsaa => 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms',
|
105
|
+
:padron => "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL",
|
106
|
+
:wsfe => 'https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL'
|
107
|
+
},
|
108
|
+
:production => {
|
109
|
+
:wsaa => 'https://wsaa.afip.gov.ar/ws/services/LoginCms',
|
110
|
+
:padron => "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL",
|
111
|
+
:wsfe => 'https://servicios1.afip.gov.ar/wsfev1/service.asmx'
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class Float
|
2
|
+
def round_with_precision(precision = nil)
|
3
|
+
precision.nil? ? round : (self * (10 ** precision)).round / (10 ** precision).to_f
|
4
|
+
end
|
5
|
+
def round_up_with_precision(precision = nil)
|
6
|
+
precision.nil? ? round : ((self * (10 ** precision)).round + 1) / (10 ** precision).to_f
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Hash
|
2
|
+
def symbolize_keys!
|
3
|
+
keys.each do |key|
|
4
|
+
self[(key.to_sym rescue key) || key] = delete(key)
|
5
|
+
end
|
6
|
+
self
|
7
|
+
end unless method_defined?(:symbolize_keys!)
|
8
|
+
|
9
|
+
def symbolize_keys
|
10
|
+
dup.symbolize_keys!
|
11
|
+
end unless method_defined?(:symbolize_keys)
|
12
|
+
|
13
|
+
def underscore_keys!
|
14
|
+
keys.each do |key|
|
15
|
+
self[(key.underscore rescue key) || key] = delete(key)
|
16
|
+
end
|
17
|
+
self
|
18
|
+
end unless method_defined?(:underscore_keys!)
|
19
|
+
|
20
|
+
def underscore_keys
|
21
|
+
dup.underscore_keys!
|
22
|
+
end unless method_defined?(:underscore_keys)
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Stolen from activesupport/lib/active_support/inflector/methods.rb, line 48
|
2
|
+
class String
|
3
|
+
def underscore
|
4
|
+
word = self.to_s.dup
|
5
|
+
word.gsub!(/::/, '/')
|
6
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
7
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
8
|
+
word.tr!("-", "_")
|
9
|
+
word.downcase!
|
10
|
+
word
|
11
|
+
end
|
12
|
+
end
|
data/lib/Afip/ctg.rb
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
module Afip
|
2
|
+
class CTG
|
3
|
+
attr_reader :client, :base_imp, :total
|
4
|
+
attr_accessor :ctg_num, :cp_num, :cod_especie, :cuit_canjeador,:rccc, :cuit_destino, :cuit_destinatario, :localidad_origen, :localidad_destino,
|
5
|
+
:cosecha, :peso, :cuit_transportista, :horas, :patente, :km, :cuit_corredor, :remitente_com, :body
|
6
|
+
|
7
|
+
def initialize(attrs = {})
|
8
|
+
Afip::AuthData.fetch("wsctg")
|
9
|
+
@client = Savon.client(
|
10
|
+
ssl_cert_key_file: Afip.pkey,
|
11
|
+
ssl_cert_file: Afip.cert,
|
12
|
+
env_namespace: :soapenv,
|
13
|
+
namespace_identifier: :ctg,
|
14
|
+
log: true,
|
15
|
+
logger: Rails.logger,
|
16
|
+
log_level: :debug,
|
17
|
+
pretty_print_xml: true,
|
18
|
+
encoding: 'UTF-8',
|
19
|
+
ssl_version: :TLSv1,
|
20
|
+
wsdl: Afip.service_url
|
21
|
+
)
|
22
|
+
|
23
|
+
@ctg_num = attrs[:ctg_num]
|
24
|
+
@cp_num = attrs[:cp_num]
|
25
|
+
@cod_especie = attrs[:cod_especie]
|
26
|
+
@cuit_canjeador = attrs[:cuit_canjeador]
|
27
|
+
@rccc = attrs[:rccc]
|
28
|
+
@cuit_destino = attrs[:cuit_destino]
|
29
|
+
@cuit_destinatario = attrs[:cuit_destinatario]
|
30
|
+
@localidad_origen = attrs[:localidad_origen]
|
31
|
+
@localidad_destino = attrs[:localidad_destino]
|
32
|
+
@cosecha = attrs[:cosecha]
|
33
|
+
@peso = attrs[:peso]
|
34
|
+
@cuit_transportista = attrs[:cuit_transportista]
|
35
|
+
@horas = attrs[:horas]
|
36
|
+
@patente = attrs[:patente]
|
37
|
+
@km = attrs[:km]
|
38
|
+
@cuit_corredor = attrs[:cuit_corredor]
|
39
|
+
@remitente_com = attrs[:remitente_com]
|
40
|
+
@cuit_chofer = attrs[:cuit_chofer]
|
41
|
+
@cant_kilos_carta_porte = attrs[:cant_kilos_carta_porte]
|
42
|
+
@establecimiento = attrs[:establecimiento]
|
43
|
+
@cuit_solicitante = attrs[:cuit_solicitante]
|
44
|
+
@fecha_desde = attrs[:fecha_desde]
|
45
|
+
@fecha_hasta = attrs[:fecha_hasta]
|
46
|
+
|
47
|
+
@body = {"request" =>{"auth" => Afip.auth_hash("wsctg")}}
|
48
|
+
end
|
49
|
+
|
50
|
+
def solicitar_ctg_inicial
|
51
|
+
pp body = setup_ctg
|
52
|
+
|
53
|
+
pp response = client.call(:solicitar_ctg_inicial,message: body)
|
54
|
+
|
55
|
+
setup_response(response.to_hash)
|
56
|
+
|
57
|
+
self.authorized?
|
58
|
+
end
|
59
|
+
|
60
|
+
def setup_ctg
|
61
|
+
|
62
|
+
datos = {
|
63
|
+
"datosSolicitarCTGInicial" =>{
|
64
|
+
"cartaPorte" => @cp_num, #long
|
65
|
+
"codigoEspecie" => @cod_especie, #int
|
66
|
+
#"cuitCanjeador" => @cuit_canjeador.to_i, #long
|
67
|
+
#"remitenteComercialComoCanjeador" => @rccc,
|
68
|
+
"cuitDestino" => @cuit_destino, #long
|
69
|
+
"cuitDestinatario" => @cuit_destinatario, #long
|
70
|
+
"codigoLocalidadOrigen" => @localidad_origen, #int
|
71
|
+
"codigoLocalidadDestino" => @localidad_destino, #int
|
72
|
+
"codigoCosecha" => @cosecha, #string
|
73
|
+
"pesoNeto" => @peso.to_i, #long
|
74
|
+
#"cuitTransportista" => @cuit_transportista.to_i, #long
|
75
|
+
#"cantHoras" => @horas, #int
|
76
|
+
#"patente" => @patente, #string
|
77
|
+
"kmARecorrer" => @km, #unsignedint
|
78
|
+
#"cuitCorredor" => @cuit_corredor.to_i, #long
|
79
|
+
#"remitenteComercialcomoProductor" => @remitente_com
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
@body["request"].merge!(datos)
|
84
|
+
return @body
|
85
|
+
end
|
86
|
+
|
87
|
+
def authorized?
|
88
|
+
!response.nil?
|
89
|
+
end
|
90
|
+
|
91
|
+
def anular_ctg
|
92
|
+
request = {
|
93
|
+
"datosAnularCTG" =>{
|
94
|
+
"cartaPorte" => @cp_num,
|
95
|
+
"ctg" => @ctg_num
|
96
|
+
}
|
97
|
+
}
|
98
|
+
body["request"].merge(request)
|
99
|
+
|
100
|
+
response = client.call(:anular_ctg, message: body)
|
101
|
+
end
|
102
|
+
|
103
|
+
def cambiar_destino_detinatario_ctg_rechazado
|
104
|
+
request = {
|
105
|
+
"datosCambiarDestinoDestinatarioCTGRechazado" =>{
|
106
|
+
"cartaPorte" => @cp_num,
|
107
|
+
"ctg" => @ctg_num,
|
108
|
+
"codigoLocalidadDestino" => @destino,
|
109
|
+
"codigoLocalidadDestinatario" => @destinatario,
|
110
|
+
"kmARecorrer" => @km
|
111
|
+
}
|
112
|
+
}
|
113
|
+
body["request"].merge(request)
|
114
|
+
|
115
|
+
response = client.call(:cambiar_destino_detinatario_ctg_rechazado, message: body)
|
116
|
+
end
|
117
|
+
|
118
|
+
def confirmar_arribo
|
119
|
+
request = {
|
120
|
+
"datosConfirmarArribo" =>{
|
121
|
+
"cartaPorte" => @cp_num,
|
122
|
+
"ctg" => @ctg_num,
|
123
|
+
"cuitTransportista" => @cuit_transportista,
|
124
|
+
"cuitChofer" => @cuit_chofer,
|
125
|
+
"cantKilosCartaPorte" => @cant_kilos_carta_porte
|
126
|
+
}
|
127
|
+
}
|
128
|
+
body["request"].merge(request)
|
129
|
+
|
130
|
+
response = client.call(:confirmar_arribo, message: body)
|
131
|
+
end
|
132
|
+
|
133
|
+
def confirmar_definitivo
|
134
|
+
request = {
|
135
|
+
"datosConfirmarDefinitivo" =>{
|
136
|
+
"cartaPorte" => @cp_num,
|
137
|
+
"ctg" => @ctg_num,
|
138
|
+
"establecimiento" => @establecimiento,
|
139
|
+
"codigoCosecha" => @cosecha,
|
140
|
+
"pesoNeto" => @peso
|
141
|
+
}
|
142
|
+
}
|
143
|
+
body["request"].merge(request)
|
144
|
+
|
145
|
+
response = client.call(:confirmar_definitivo, message: body)
|
146
|
+
end
|
147
|
+
|
148
|
+
def consultar_cosechas
|
149
|
+
response = client.call(:obtener_cosechas, message: body)
|
150
|
+
return response["arrayCosechas"]
|
151
|
+
end
|
152
|
+
|
153
|
+
def consultar_constancia_ctg_pdf
|
154
|
+
request = {
|
155
|
+
"ctg" => @ctg_num
|
156
|
+
}
|
157
|
+
|
158
|
+
body["request"].merge(request)
|
159
|
+
|
160
|
+
pp response = client.call(:consultar_constancia_ctgpdf, message: body)
|
161
|
+
end
|
162
|
+
|
163
|
+
def consultar_ctg
|
164
|
+
request = {
|
165
|
+
"consultarCTGDatos" =>{
|
166
|
+
"cartaPorte" => @cp_num,
|
167
|
+
"ctg" => @ctg_num,
|
168
|
+
"patente" => @patente,
|
169
|
+
"cuitSolicitante" => @cuit_solicitante,
|
170
|
+
"cuitDestino" => @destino,
|
171
|
+
"fechaEmisionDesde" => @fecha_desde,
|
172
|
+
"fechaEmisionHsta" => @fecha_hasta,
|
173
|
+
"cuitCorredor" => @cuit_corredor
|
174
|
+
}
|
175
|
+
}
|
176
|
+
body["request"].merge(request)
|
177
|
+
|
178
|
+
response = client.call(:consultar_ctg, message: body)
|
179
|
+
end
|
180
|
+
|
181
|
+
def consultar_ctg_rechazados
|
182
|
+
response = client.call(:consultar_ctg_rechazados, message: body)
|
183
|
+
return response.to_hash["response"]["arrayConsultarCTGRechazados"]
|
184
|
+
end
|
185
|
+
|
186
|
+
def consultar_detalle_ctg
|
187
|
+
request = {
|
188
|
+
"ctg" => @ctg_num
|
189
|
+
}
|
190
|
+
|
191
|
+
body["request"].merge(request)
|
192
|
+
|
193
|
+
response = client.call(:consultar_constancia_ctg_pdf, message: body)
|
194
|
+
return response.to_hash["response"]["consultarDetalleCTGDatos"]
|
195
|
+
end
|
196
|
+
|
197
|
+
def consultar_especies
|
198
|
+
response = client.call(:consultar_especies, message: body)
|
199
|
+
response.body[:consultar_especies_response][:response][:array_especies][:especie].map{|c| [c[:codigo],c[:descripcion]]}
|
200
|
+
end
|
201
|
+
|
202
|
+
def consultar_establecimientos
|
203
|
+
response = client.call(:consultar_establecimientos, message: body)
|
204
|
+
response.body[:consultar_especies_response][:response][:array_establecimientos][:establecimiento].map{|c| [c]}
|
205
|
+
end
|
206
|
+
|
207
|
+
def consultar_provincias
|
208
|
+
response = client.call(:consultar_provincias, message: body)
|
209
|
+
response.body[:consultar_provincias_response][:consultar_provincias_response][:array_provincias][:provincia].map{|c| [c[:codigo],c[:descripcion]]}
|
210
|
+
end
|
211
|
+
|
212
|
+
def consultar_cosechas
|
213
|
+
response = client.call(:consultar_cosechas, message: body)
|
214
|
+
response.body[:consultar_cosechas_response][:response][:array_cosechas][:cosecha].map{|c| [c[:codigo],c[:descripcion]]}
|
215
|
+
end
|
216
|
+
|
217
|
+
def consultar_localidades(city)
|
218
|
+
body["request"]["codigoProvincia"] = city
|
219
|
+
response = client.call(:consultar_localidades_por_provincia, message: body)
|
220
|
+
if response.body[:consultar_localidades_por_provincia_response][:response][:array_localidades][:localidad].class.name != "Array"
|
221
|
+
[response.body[:consultar_localidades_por_provincia_response][:response][:array_localidades][:localidad]].map{|c| [c[:codigo],c[:descripcion]]}
|
222
|
+
else
|
223
|
+
response.body[:consultar_localidades_por_provincia_response][:response][:array_localidades][:localidad].map{|c| [c[:codigo],c[:descripcion]]}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
private
|
228
|
+
|
229
|
+
def setup_response(response)
|
230
|
+
# TODO: turn this into an all-purpose Response class
|
231
|
+
pp response
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
data/lib/Afip/padron.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
module Afip
|
2
|
+
class Padron
|
3
|
+
attr_reader :client, :body, :fault_code
|
4
|
+
attr_accessor :dni, :tipo, :data
|
5
|
+
def initialize(attrs = {})
|
6
|
+
Afip::AuthData.environment = Afip.environment || :production
|
7
|
+
url = Afip::AuthData.environment == :production ? "aws" : "awshomo"
|
8
|
+
Afip.service_url = "https://#{url}.afip.gov.ar/sr-padron/webservices/personaServiceA4?WSDL"
|
9
|
+
Afip.cuit ||= "20368642682"
|
10
|
+
Afip.cert ||= "#{Afip.root}/lib/Afip/certs/desideral_prod.crt"
|
11
|
+
Afip.pkey ||= "#{Afip.root}/lib/Afip/certs/desideral.key"
|
12
|
+
Afip::AuthData.fetch("ws_sr_padron_a4")
|
13
|
+
|
14
|
+
@client = Savon.client(
|
15
|
+
ssl_cert_key_file: Afip.pkey,
|
16
|
+
ssl_cert_file: Afip.cert,
|
17
|
+
env_namespace: :soapenv,
|
18
|
+
namespace_identifier: :a4,
|
19
|
+
encoding: 'UTF-8',
|
20
|
+
wsdl: Afip.service_url
|
21
|
+
)
|
22
|
+
|
23
|
+
@dni = attrs[:dni].rjust(8, "0")
|
24
|
+
@tipo = attrs[:tipo]
|
25
|
+
@cuit = get_cuit
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_persona
|
29
|
+
body = setup_body
|
30
|
+
|
31
|
+
response = client.call(:get_persona,message: body)
|
32
|
+
rescue Savon::SOAPFault => error
|
33
|
+
if !error.blank?
|
34
|
+
@fault_code = error.to_hash[:fault][:faultstring]
|
35
|
+
else
|
36
|
+
@fault_code = nil
|
37
|
+
end
|
38
|
+
return response
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_data
|
42
|
+
@data = get_persona
|
43
|
+
if fault_code.nil?
|
44
|
+
set_data
|
45
|
+
else
|
46
|
+
return nil
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_data
|
52
|
+
if not data.body[:get_persona_response][:persona_return][:persona][:actividad].nil?
|
53
|
+
{
|
54
|
+
:name => set_name(data),
|
55
|
+
:cuit => data.body[:get_persona_response][:persona_return][:persona][:id_persona],
|
56
|
+
:cp => data.body[:get_persona_response][:persona_return][:persona][:domicilio].last[:cod_postal],
|
57
|
+
:address => data.body[:get_persona_response][:persona_return][:persona][:domicilio].last[:direccion],
|
58
|
+
:city_id => data.body[:get_persona_response][:persona_return][:persona][:domicilio].last[:id_provincia],
|
59
|
+
:city => PROVINCIAS[data.body[:get_persona_response][:persona_return][:persona][:domicilio].last[:id_provincia]],
|
60
|
+
:locality => data.body[:get_persona_response][:persona_return][:persona][:domicilio].last[:localidad],
|
61
|
+
:birthday => data.body[:get_persona_response][:persona_return][:persona][:fecha_nacimiento].to_date
|
62
|
+
}
|
63
|
+
else
|
64
|
+
{
|
65
|
+
:name => data.body[:get_persona_response][:persona_return][:persona][:apellido])
|
66
|
+
:cuit => data.body[:get_persona_response][:persona_return][:persona][:id_persona],
|
67
|
+
:cp => data.body[:get_persona_response][:persona_return][:persona].try(:[], :domicilio).try(:[], :cod_postal),
|
68
|
+
:address => data.body[:get_persona_response][:persona_return][:persona].try(:[], :domicilio).try(:[], :direccion),
|
69
|
+
:city_id => data.body[:get_persona_response][:persona_return][:persona].try(:[], :domicilio).try(:[], :id_provincia),
|
70
|
+
:city => PROVINCIAS[data.body[:get_persona_response][:persona_return][:persona].try(:[], :domicilio).try(:[], :id_provincia)],
|
71
|
+
:locality => data.body[:get_persona_response][:persona_return][:persona].try(:[], :domicilio).try(:[], :localidad),
|
72
|
+
:birthday => data.body[:get_persona_response][:persona_return][:persona][:fecha_nacimiento].to_date
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def set_name(data)
|
78
|
+
return data.body[:get_persona_response][:persona_return][:persona][:nombre] + data.body[:get_persona_response][:persona_return][:persona][:apellido]
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.divide_name(full_name)
|
82
|
+
full_name = full_name.strip.split(/\s+/)
|
83
|
+
last_name = ''
|
84
|
+
last = (full_name.count / 2) - 1
|
85
|
+
(0..last).each do |i|
|
86
|
+
if i != last
|
87
|
+
last_name += full_name[i] + ' '
|
88
|
+
else
|
89
|
+
last_name += full_name[i]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
full_name = full_name - (last_name.strip.split(/\s+/))
|
93
|
+
first_name = full_name.join(", ").gsub(",","").split.map(&:capitalize).join(' ')
|
94
|
+
last_name = last_name.split.map(&:capitalize).join(' ')
|
95
|
+
return [last_name, first_name]
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_cuit
|
99
|
+
if dni.length == 11
|
100
|
+
@cuit = @dni
|
101
|
+
else
|
102
|
+
@cuit = calculate_cuit
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def calculate_cuit
|
107
|
+
multiplicador = "2345672345"
|
108
|
+
|
109
|
+
case tipo
|
110
|
+
when "F"
|
111
|
+
xy = 27
|
112
|
+
xy_dni = "27#{dni}"
|
113
|
+
when "M"
|
114
|
+
xy = 20
|
115
|
+
xy_dni = "20#{dni}"
|
116
|
+
end
|
117
|
+
verificador = 0
|
118
|
+
(0..9).each do |i|
|
119
|
+
verificador += (xy_dni.reverse[i].to_i * multiplicador[i].to_i)
|
120
|
+
end
|
121
|
+
verificador
|
122
|
+
z = verificador - (verificador / 11 * 11)
|
123
|
+
|
124
|
+
case z
|
125
|
+
when 0
|
126
|
+
z = 0
|
127
|
+
when 1
|
128
|
+
if tipo == "M"
|
129
|
+
z = 9
|
130
|
+
xy = 23
|
131
|
+
elsif tipo == "F"
|
132
|
+
z = 4
|
133
|
+
xy = 23
|
134
|
+
else
|
135
|
+
z = 11 - z
|
136
|
+
end
|
137
|
+
else
|
138
|
+
z = 11 - z
|
139
|
+
end
|
140
|
+
|
141
|
+
return "#{xy}#{dni}#{z}"
|
142
|
+
end
|
143
|
+
|
144
|
+
def setup_body
|
145
|
+
body = {
|
146
|
+
'token' => Afip::TOKEN,
|
147
|
+
'sign' => Afip::SIGN,
|
148
|
+
'cuitRepresentada' => Afip.cuit,
|
149
|
+
'idPersona' => @cuit.to_s
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
PROVINCIAS = {
|
154
|
+
"0" => 'CIUDAD AUTONOMA BUENOS AIRES',
|
155
|
+
"1" => 'BUENOS AIRES',
|
156
|
+
"2" => 'CATAMARCA',
|
157
|
+
"3" => 'CORDOBA',
|
158
|
+
"4" => 'CORRIENTES',
|
159
|
+
"5" => 'ENTRE RIOS',
|
160
|
+
"6" => 'JUJUY',
|
161
|
+
"7" => 'MENDOZA',
|
162
|
+
"8" => 'LA RIOJA',
|
163
|
+
"9" => 'SALTA',
|
164
|
+
"10" => 'SAN JUAN',
|
165
|
+
"11" => 'SAN LUIS',
|
166
|
+
"12" => 'SANTA FE',
|
167
|
+
"13" => 'SANTIAGO DEL ESTERO',
|
168
|
+
"14" => 'TUCUMAN',
|
169
|
+
"16" => 'CHACO',
|
170
|
+
"17" => 'CHUBUT',
|
171
|
+
"18" => 'FORMOSA',
|
172
|
+
"19" => 'MISIONES',
|
173
|
+
"20" => 'NEUQUEN',
|
174
|
+
"21" => 'LA PAMPA',
|
175
|
+
"22" => 'RIO NEGRO',
|
176
|
+
"23" => 'SANTA CRUZ',
|
177
|
+
"24" => 'TIERRA DEL FUEGO'
|
178
|
+
}
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
|