snoopy_afip 2.1.1 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/CHANGELOG +23 -23
- data/README.textile +236 -0
- data/lib/snoopy_afip/authentication_adapter.rb +119 -0
- data/lib/snoopy_afip/authorize_adapter.rb +178 -0
- data/lib/snoopy_afip/bill.rb +124 -203
- data/lib/snoopy_afip/client.rb +20 -0
- data/lib/snoopy_afip/constants.rb +69 -65
- data/lib/snoopy_afip/core_ext/hash.rb +11 -0
- data/lib/snoopy_afip/exceptions.rb +74 -0
- data/lib/snoopy_afip/version.rb +1 -1
- data/lib/snoopy_afip.rb +10 -10
- data/snoopy_afip.gemspec +7 -7
- metadata +74 -89
- data/lib/snoopy_afip/auth_data.rb +0 -46
- data/lib/snoopy_afip/authorizer.rb +0 -10
- data/spec/snoopy_afip/auth_data_spec.rb +0 -12
data/lib/snoopy_afip/bill.rb
CHANGED
@@ -1,254 +1,175 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
module Snoopy
|
3
3
|
class Bill
|
4
|
-
|
4
|
+
attr_accessor :total_net, :document_num, :document_type, :concept, :currency, :result,
|
5
|
+
:cbte_asoc_num, :cae, :service_date_to, :due_date,
|
6
|
+
:number, :alicivas, :cuit, :sale_point, :service_date_from,
|
7
|
+
:due_date_cae, :voucher_date, :process_date, :imp_iva, :cbte_asoc_sale_point,
|
8
|
+
:receiver_iva_cond, :issuer_iva_cond, :errors
|
5
9
|
|
6
|
-
|
10
|
+
ATTRIBUTES = [ :total_net, :document_num, :document_type, :concept, :currency, :result,
|
11
|
+
:cbte_asoc_num, :cae, :service_date_to, :due_date,
|
12
|
+
:number, :alicivas, :cuit, :sale_point, :service_date_from,
|
13
|
+
:due_date_cae, :voucher_date, :process_date, :imp_iva, :cbte_asoc_sale_point,
|
14
|
+
:receiver_iva_cond, :issuer_iva_cond, :errors ]
|
7
15
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
:pkey, :cert, :cuit, :punto_venta, :condicion_iva_emisor, :auth, :errors,
|
12
|
-
:cae, :resultado, :fecha_proceso, :vencimiento_cae, :fecha_comprobante,
|
13
|
-
:observaciones, :events, :imp_iva, :backtrace
|
16
|
+
TAX_ATTRIBUTES = [ :id, :amount, :taxeable_base ]
|
17
|
+
|
18
|
+
ATTRIBUTES_PRECENSE = [:total_net, :concept, :receiver_iva_cond, :alicivas, :document_type, :service_date_from, :service_date_to, :sale_point, :issuer_iva_cond]
|
14
19
|
|
15
20
|
def initialize(attrs={})
|
16
|
-
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@
|
32
|
-
@
|
33
|
-
@
|
34
|
-
@
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
21
|
+
# attrs = attrs.deep_symbolize_keys
|
22
|
+
@cuit = attrs[:cuit]
|
23
|
+
@result = nil
|
24
|
+
@number = nil
|
25
|
+
@errors = {}
|
26
|
+
@concept = attrs[:concept] || Snoopy.default_concept
|
27
|
+
@imp_iva = attrs[:imp_iva] # Monto total de impuestos
|
28
|
+
@currency = attrs[:currency] || Snoopy.default_currency
|
29
|
+
@alicivas = attrs[:alicivas]
|
30
|
+
@total_net = attrs[:total_net] || 0
|
31
|
+
@sale_point = attrs[:sale_point]
|
32
|
+
@document_num = attrs[:document_num]
|
33
|
+
@cbte_asoc_num = attrs[:cbte_asoc_num] # Esto es el numero de factura para la nota de credito
|
34
|
+
@document_type = attrs[:document_type] || Snoopy.default_document_type
|
35
|
+
@issuer_iva_cond = attrs[:issuer_iva_cond]
|
36
|
+
@service_date_to = attrs[:service_date_to]
|
37
|
+
@service_date_from = attrs[:service_date_from]
|
38
|
+
@receiver_iva_cond = attrs[:receiver_iva_cond]
|
39
|
+
@cbte_asoc_to_sale_point = attrs[:cbte_asoc_to_sale_point] # Esto es el punto de venta de la factura para la nota de credito
|
40
|
+
end
|
41
|
+
|
42
|
+
# def self.bill_request(number, attrs={})
|
43
|
+
# bill = Snoopy::Bill.new(attrs)
|
44
|
+
# bill.response = bill.client_call( :fe_comp_consultar,
|
45
|
+
# :message => {"Auth" => bill.auth,
|
46
|
+
# "FeCompConsReq" => {"CbteTipo" => bill.cbte_type, "PtoVta" => bill.sale_point, "CbteNro" => number.to_s}})
|
47
|
+
# bill.parse_fe_comp_consultar_response
|
48
|
+
# bill
|
49
|
+
# rescue => e
|
50
|
+
# binding.pry
|
51
|
+
# end
|
52
|
+
|
53
|
+
# Para probar que la conexion con afip es correcta, si este metodo devuelve true, es posible realizar cualquier consulta al ws de la AFIP.
|
54
|
+
# def connection_valid?
|
55
|
+
# # result = client.call(:fe_dummy).body[:fe_dummy_response][:fe_dummy_result]
|
56
|
+
# result = client_call(:fe_dummy)[:fe_dummy_response][:fe_dummy_result]
|
57
|
+
# @afip_observations[:db_server] = result[:db_server]
|
58
|
+
# @afip_observations[:app_server] = result[:app_server]
|
59
|
+
# @afip_observations[:auth_server] = result[:auth_server]
|
60
|
+
# result[:app_server] == 'OK' and result[:db_server] == 'OK' and result[:auth_server] == 'OK'
|
61
|
+
# end
|
39
62
|
|
40
63
|
def exchange_rate
|
41
|
-
return 1 if
|
42
|
-
response = client.fe_param_get_cotizacion do |soap|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
response.to_hash[:fe_param_get_cotizacion_response][:fe_param_get_cotizacion_result][:result_get][:mon_cotiz].to_f
|
64
|
+
return 1 if currency == :peso
|
65
|
+
# response = client.fe_param_get_cotizacion do |soap|
|
66
|
+
# soap.namespaces["xmlns"] = "http://ar.gov.afip.dif.FEV1/"
|
67
|
+
# soap.body = body.merge!({"MonId" => Snoopy::CURRENCY[currency][:code]})
|
68
|
+
# end
|
69
|
+
# response.to_hash[:fe_param_get_cotizacion_response][:fe_param_get_cotizacion_result][:result_get][:mon_cotiz].to_f
|
47
70
|
end
|
48
71
|
|
49
72
|
def total
|
50
|
-
@total =
|
73
|
+
@total = total_net.zero? ? 0 : (total_net + iva_sum).round(2)
|
51
74
|
end
|
52
75
|
|
53
76
|
def iva_sum
|
54
|
-
@iva_sum = alicivas.
|
77
|
+
@iva_sum = alicivas.map{|aliciva| aliciva[:amount].to_f }.inject(:+).to_f.round_with_precision(2)
|
55
78
|
end
|
56
79
|
|
57
80
|
def cbte_type
|
58
|
-
Snoopy::BILL_TYPE[
|
81
|
+
Snoopy::BILL_TYPE[receiver_iva_cond.to_sym]
|
59
82
|
end
|
60
83
|
|
61
|
-
def
|
62
|
-
|
63
|
-
:ssl_cert_key_file => pkey,
|
64
|
-
:ssl_cert_file => cert,
|
65
|
-
:ssl_version => :TLSv1,
|
66
|
-
:read_timeout => 90,
|
67
|
-
:open_timeout => 90,
|
68
|
-
:headers => { "Accept-Encoding" => "gzip, deflate", "Connection" => "Keep-Alive" },
|
69
|
-
:pretty_print_xml => true,
|
70
|
-
:namespaces => {"xmlns" => "http://ar.gov.afip.dif.FEV1/"} )
|
84
|
+
def approved?
|
85
|
+
result == 'A'
|
71
86
|
end
|
72
87
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
88
|
+
def rejected?
|
89
|
+
result == 'R'
|
90
|
+
end
|
76
91
|
|
77
|
-
|
78
|
-
|
79
|
-
@numero = resp.to_hash[:fe_comp_ultimo_autorizado_response][:fe_comp_ultimo_autorizado_result][:cbte_nro].to_i + 1 if @errors.empty?
|
92
|
+
def partial_approved?
|
93
|
+
result == 'P'
|
80
94
|
end
|
81
95
|
|
82
|
-
def
|
83
|
-
|
96
|
+
def valid?
|
97
|
+
validate!
|
84
98
|
end
|
85
99
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
"FeDetReq" => {
|
93
|
-
"FECAEDetRequest" => {
|
94
|
-
"Concepto" => Snoopy::CONCEPTOS[concepto],
|
95
|
-
"DocTipo" => Snoopy::DOCUMENTOS[tipo_documento],
|
96
|
-
"CbteFch" => today,
|
97
|
-
"ImpTotConc" => 0.00,
|
98
|
-
"MonId" => Snoopy::MONEDAS[moneda][:codigo],
|
99
|
-
"MonCotiz" => exchange_rate,
|
100
|
-
"ImpOpEx" => 0.00,
|
101
|
-
"ImpTrib" => 0.00 }}}}
|
102
|
-
|
103
|
-
unless condicion_iva_emisor.to_sym == :responsable_monotributo
|
104
|
-
_alicivas = alicivas.collect do |aliciva|
|
105
|
-
id = if aliciva.has_key?('id'); aliciva['id']; else aliciva[:id]; end
|
106
|
-
importe = if aliciva.has_key?('importe'); aliciva['importe']; else aliciva[:importe]; end
|
107
|
-
base_imp = if aliciva.has_key?('base_imp'); aliciva['base_imp']; else aliciva[:base_imp]; end
|
108
|
-
{ "Id" => Snoopy::ALIC_IVA[id], "BaseImp" => base_imp, "Importe" => importe }
|
109
|
-
end
|
110
|
-
fecaereq["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"]["Iva"] = { "AlicIva" => _alicivas }
|
111
|
-
end
|
100
|
+
def to_h
|
101
|
+
Hash[*instance_variables.map { |v|
|
102
|
+
[v.to_s.sub('@', '').to_sym, instance_variable_get(v)]
|
103
|
+
}.flatten]
|
104
|
+
end
|
105
|
+
alias :to_hash :to_h
|
112
106
|
|
113
|
-
|
107
|
+
private
|
114
108
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
109
|
+
def validate!
|
110
|
+
# validate_attributes_name(attrs)
|
111
|
+
@errors = {}
|
112
|
+
validate_attributes_presence
|
113
|
+
validate_standar_values
|
114
|
+
end
|
119
115
|
|
120
|
-
|
116
|
+
def validate_attributes_presence
|
117
|
+
missing_attributes = []
|
118
|
+
ATTRIBUTES_PRECENSE.each { |_attr| missing_attributes << _attr if (self.send(_attr).blank? || self.send(_attr).nil?) }
|
121
119
|
|
122
|
-
|
123
|
-
detail.merge!({ "FchServDesde" => fecha_servicio_desde || today,
|
124
|
-
"FchServHasta" => fecha_servicio_hasta || today,
|
125
|
-
"FchVtoPago" => due_date || today})
|
126
|
-
end
|
120
|
+
@alicivas.each { |imp| missing_attributes += Snoopy::Bill::TAX_ATTRIBUTES - imp.keys }
|
127
121
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
"Tipo" => cbte_type }}})
|
122
|
+
missing_attributes.uniq.each do |attr|
|
123
|
+
@errors[attr.to_sym] = [] unless errors.has_key?(attr)
|
124
|
+
@errors[attr.to_sym] << Snoopy::Exception::Bill::MissingAttributes.new(attr).message
|
132
125
|
end
|
133
126
|
|
134
|
-
@body = { "Auth" => generate_auth_file }.merge!(fecaereq)
|
135
127
|
end
|
136
128
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
parse_fecae_solicitar_response
|
144
|
-
end
|
145
|
-
rescue => e #Curl::Err::GotNothingError, Curl::Err::TimeoutError
|
146
|
-
@errors = e.message
|
147
|
-
@backtrace = e.backtrace
|
129
|
+
def validate_standar_values
|
130
|
+
status = true
|
131
|
+
unless Snoopy::CURRENCY.keys.include?(@currency.to_sym)
|
132
|
+
@errors[:currency] = [] unless errors.has_key?(:currency)
|
133
|
+
@errors[:currency] << Snoopy::Exception::Bill::InvalidValueAttribute.new("Invalid value #{@currency}, Possible values #{Snoopy::CURRENCY.keys}").message
|
134
|
+
status = false unless errors.empty?
|
148
135
|
end
|
149
|
-
!@response.nil?
|
150
|
-
end
|
151
|
-
|
152
|
-
def aprobada?; @resultado == "A"; end
|
153
|
-
def parcial?; @resultado == "P"; end
|
154
|
-
def rechazada?; @resultado == "R"; end
|
155
136
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
@observaciones << "app_server: #{result[:app_server]}, db_server: #{result[:db_server]}, auth_server: #{result[:auth_server]}"
|
161
|
-
result[:app_server] == "OK" and result[:db_server] == "OK" and result[:auth_server] == "OK"
|
162
|
-
rescue => e
|
163
|
-
@errors << e.message
|
164
|
-
@backtrace = e.backtrace
|
165
|
-
false
|
137
|
+
unless Snoopy::IVA_COND.include?(@issuer_iva_cond.to_sym)
|
138
|
+
@errors[:issuer_iva_cond] = [] unless errors.has_key?(:issuer_iva_cond)
|
139
|
+
@errors[:issuer_iva_cond] << Snoopy::Exception::Bill::InvalidValueAttribute.new("Invalid value #{@issuer_iva_cond}. Possible values #{Snoopy::IVA_COND}").message
|
140
|
+
status = false unless errors.empty?
|
166
141
|
end
|
167
|
-
end
|
168
142
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
end
|
174
|
-
rescue
|
175
|
-
@observaciones << "Ocurrió un error al parsear las observaciones de AFIP"
|
143
|
+
unless Snoopy::BILL_TYPE.keys.include?(@receiver_iva_cond.to_sym)
|
144
|
+
@errors[:receiver_iva_cond] = [] unless errors.has_key?(:receiver_iva_cond)
|
145
|
+
@errors[:receiver_iva_cond] << Snoopy::Exception::Bill::InvalidValueAttribute.new("Invalid value #{@receiver_iva_cond}. Possible values #{Snoopy::BILL_TYPE.keys}").message
|
146
|
+
status = false unless errors.empty?
|
176
147
|
end
|
177
|
-
end
|
178
148
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
end
|
184
|
-
rescue
|
185
|
-
@errors << "Ocurrió un error al parsear los errores de AFIP"
|
149
|
+
unless Snoopy::DOCUMENTS.keys.include?(@document_type)
|
150
|
+
@errors[:document_type] = [] unless errors.has_key?(:document_type)
|
151
|
+
@errors[:document_type] << Snoopy::Exception::Bill::InvalidValueAttribute.new("Invalid value #{@document_type}. Possible values #{Snoopy::DOCUMENTS.keys}").message
|
152
|
+
status = false unless errors.empty?
|
186
153
|
end
|
187
|
-
end
|
188
154
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
194
|
-
rescue
|
195
|
-
@events << "Ocurrió un error al parsear los eventos de AFIP"
|
155
|
+
unless Snoopy::CONCEPTS.keys.include?(@concept)
|
156
|
+
@errors[:concept] = [] unless errors.has_key?(:concept)
|
157
|
+
@errors[:concept] << Snoopy::Exception::Bill::InvalidValueAttribute.new("Invalid value #{@concept}. Possible values #{Snoopy::CONCEPTS.keys}").message
|
158
|
+
status = false unless errors.empty?
|
196
159
|
end
|
160
|
+
status
|
197
161
|
end
|
198
162
|
|
199
|
-
def
|
200
|
-
|
201
|
-
|
202
|
-
fecae_result = @response[:fecae_solicitar_response][:fecae_solicitar_result] rescue {}
|
203
|
-
|
204
|
-
@cae = fecae_response[:cae]
|
205
|
-
@numero = fecae_response[:cbte_desde]
|
206
|
-
@resultado = fecae_response[:resultado]
|
207
|
-
@vencimiento_cae = fecae_response[:cae_fch_vto]
|
208
|
-
@fecha_comprobante = fecae_response[:cbte_fch]
|
209
|
-
|
210
|
-
@fecha_proceso = fe_cab_resp[:fch_proceso]
|
211
|
-
|
212
|
-
parse_observations(fecae_response.delete(:observaciones)) if fecae_response.has_key? :observaciones
|
213
|
-
parse_errors(fecae_result[:errors]) if fecae_result.has_key? :errors
|
214
|
-
parse_events(fecae_result[:events]) if fecae_result.has_key? :events
|
215
|
-
end
|
163
|
+
# def validate_attributes_name attrs
|
164
|
+
# attrs_not_found = attrs.keys - Snoopy::Bill::ATTRIBUTES
|
165
|
+
# imp_atts_not_found = []
|
216
166
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
unless result_get.nil?
|
222
|
-
@cae = result_get[:cod_autorizacion]
|
223
|
-
@imp_iva = result_get[:imp_iva]
|
224
|
-
@numero = result_get[:cbte_desde]
|
225
|
-
@resultado = result_get[:resultado]
|
226
|
-
@fecha_proceso = result_get[:fch_proceso]
|
227
|
-
@vencimiento_cae = result_get[:fch_vto]
|
228
|
-
@numero_documento = result_get[:doc_numero]
|
229
|
-
@fecha_comprobante = result_get[:cbte_fch]
|
230
|
-
@fecha_servicio_desde = result_get[:fch_serv_desde]
|
231
|
-
@fecha_servicio_hasta = result_get[:fch_serv_hasta]
|
232
|
-
parse_events(result_get[:observaciones]) if result_get.has_key? :observaciones
|
233
|
-
end
|
234
|
-
|
235
|
-
self.parse_events(fe_comp_consultar_result[:errors]) if fe_comp_consultar_result and fe_comp_consultar_result.has_key? :errors
|
236
|
-
self.parse_events(fe_comp_consultar_result[:events]) if fe_comp_consultar_result and fe_comp_consultar_result.has_key? :events
|
237
|
-
end
|
238
|
-
|
239
|
-
def self.bill_request(numero, attrs={})
|
240
|
-
bill = new(attrs)
|
241
|
-
begin
|
242
|
-
bill.response = bill.client.call( :fe_comp_consultar,
|
243
|
-
:message => {"Auth" => bill.generate_auth_file,
|
244
|
-
"FeCompConsReq" => {"CbteTipo" => bill.cbte_type, "PtoVta" => bill.punto_venta, "CbteNro" => numero.to_s}})
|
245
|
-
bill.parse_fe_comp_consultar_response
|
246
|
-
rescue => e
|
247
|
-
bill.errors << e.message
|
248
|
-
bill.backtrace = e.backtrace
|
249
|
-
end
|
250
|
-
bill
|
251
|
-
end
|
167
|
+
# if attrs.has_key?(:alicivas)
|
168
|
+
# attrs[:alicivas].each { |imp| imp_atts_not_found += imp.keys - Snoopy::Bill::TAX_ATTRIBUTES }
|
169
|
+
# end
|
252
170
|
|
171
|
+
# _attrs = attrs_not_found + imp_atts_not_found.uniq
|
172
|
+
# raise Snoopy::Exception::NonExistAttributes.new(_attrs.join(', ')) if _attrs.present?
|
173
|
+
# end
|
253
174
|
end
|
254
175
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Snoopy
|
2
|
+
class Client
|
3
|
+
attr_accessor :savon
|
4
|
+
|
5
|
+
def initialize(attrs)
|
6
|
+
@savon = Savon.client(attrs)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call service, args={}
|
10
|
+
Timeout::timeout(5) do
|
11
|
+
savon.call(service, args).body
|
12
|
+
end
|
13
|
+
rescue Timeout::Error
|
14
|
+
raise Snoopy::Exception::ServerTimeout.new
|
15
|
+
rescue => e
|
16
|
+
raise Snoopy::Exception::ClientError.new(e.message)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -1,72 +1,77 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Snoopy
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
3
|
+
CBTE_TYPE = { '01' => 'Factura A',
|
4
|
+
'02' => 'Nota de Débito A',
|
5
|
+
'03' => 'Nota de Crédito A',
|
6
|
+
'04' => 'Recibos A',
|
7
|
+
'05' => 'Notas de Venta al contado A',
|
8
|
+
'06' => 'Factura B',
|
9
|
+
'07' => 'Nota de Debito B',
|
10
|
+
'08' => 'Nota de Credito B',
|
11
|
+
'09' => 'Recibos B',
|
12
|
+
'10' => 'Notas de Venta al contado B',
|
13
|
+
'11' => 'Factura C',
|
14
|
+
'13' => 'Nota de Crédito C',
|
15
|
+
'34' => 'Cbtes. A del Anexo I, Apartado A,inc.f),R.G.Nro. 1415',
|
16
|
+
'35' => 'Cbtes. B del Anexo I,Apartado A,inc. f),R.G. Nro. 1415',
|
17
|
+
'39' => 'Otros comprobantes A que cumplan con R.G.Nro. 1415',
|
18
|
+
'40' => 'Otros comprobantes B que cumplan con R.G.Nro. 1415',
|
19
|
+
'60' => 'Cta de Vta y Liquido prod. A',
|
20
|
+
'61' => 'Cta de Vta y Liquido prod. B',
|
21
|
+
'63' => 'Liquidacion A',
|
22
|
+
'64' => 'Liquidacion B' }
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
"Productos y Servicios" => "03" }
|
24
|
+
RESPONSABLE_INSCRIPTO = :responsable_inscripto
|
25
|
+
RESPONSABLE_MONOTRIBUTO = :responsable_monotributo
|
27
26
|
|
28
|
-
|
29
|
-
"CUIL" => "86",
|
30
|
-
"CDI" => "87",
|
31
|
-
"LE" => "89",
|
32
|
-
"LC" => "90",
|
33
|
-
"CI Extranjera" => "91",
|
34
|
-
"en tramite" => "92",
|
35
|
-
"Acta Nacimiento" => "93",
|
36
|
-
"CI Bs. As. RNP" => "95",
|
37
|
-
"DNI" => "96",
|
38
|
-
"Pasaporte" => "94",
|
39
|
-
"Doc. (Otro)" => "99",
|
40
|
-
"CI Policía Federal" => '00',
|
41
|
-
"CI Buenos Aires" => '01',
|
42
|
-
"CI Catamarca" => '02',
|
43
|
-
"CI Córdoba" => '03',
|
44
|
-
"CI Corrientes" => '04',
|
45
|
-
"CI Entre Ríos" => '05',
|
46
|
-
"CI Jujuy" => '06',
|
47
|
-
"CI Mendoza" => '07',
|
48
|
-
"CI La Rioja" => '08',
|
49
|
-
"CI Salta" => '09',
|
50
|
-
"CI San Juan" => '10',
|
51
|
-
"CI San Luis" => '11',
|
52
|
-
"CI Santa Fe" => '12',
|
53
|
-
"CI Santiago del Estero" => '13',
|
54
|
-
"CI Tucumán" => '14',
|
55
|
-
"CI Chaco" => '16',
|
56
|
-
"CI Chubut" => '17',
|
57
|
-
"CI Formosa" => '18',
|
58
|
-
"CI Misiones" => '19',
|
59
|
-
"CI Neuquén" => '20',
|
60
|
-
"CI La Pampa" => '21',
|
61
|
-
"CI Río Negro" => '22',
|
62
|
-
"CI Santa Cruz" => '23',
|
63
|
-
"CI Tierra del Fuego" => '24' }
|
27
|
+
IVA_COND = [ RESPONSABLE_MONOTRIBUTO, RESPONSABLE_INSCRIPTO ]
|
64
28
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
29
|
+
CONCEPTS = { 'Productos' => '01',
|
30
|
+
'Servicios' => '02',
|
31
|
+
'Productos y Servicios' => '03' }
|
32
|
+
|
33
|
+
DOCUMENTS = { 'CUIT' => '80',
|
34
|
+
'CUIL' => '86',
|
35
|
+
'CDI' => '87',
|
36
|
+
'LE' => '89',
|
37
|
+
'LC' => '90',
|
38
|
+
'CI Extranjera' => '91',
|
39
|
+
'en tramite' => '92',
|
40
|
+
'Acta Nacimiento' => '93',
|
41
|
+
'CI Bs. As. RNP' => '95',
|
42
|
+
'DNI' => '96',
|
43
|
+
'Pasaporte' => '94',
|
44
|
+
'Doc. (Otro)' => '99',
|
45
|
+
'CI Policía Federal' => '00',
|
46
|
+
'CI Buenos Aires' => '01',
|
47
|
+
'CI Catamarca' => '02',
|
48
|
+
'CI Córdoba' => '03',
|
49
|
+
'CI Corrientes' => '04',
|
50
|
+
'CI Entre Ríos' => '05',
|
51
|
+
'CI Jujuy' => '06',
|
52
|
+
'CI Mendoza' => '07',
|
53
|
+
'CI La Rioja' => '08',
|
54
|
+
'CI Salta' => '09',
|
55
|
+
'CI San Juan' => '10',
|
56
|
+
'CI San Luis' => '11',
|
57
|
+
'CI Santa Fe' => '12',
|
58
|
+
'CI Santiago del Estero' => '13',
|
59
|
+
'CI Tucumán' => '14',
|
60
|
+
'CI Chaco' => '16',
|
61
|
+
'CI Chubut' => '17',
|
62
|
+
'CI Formosa' => '18',
|
63
|
+
'CI Misiones' => '19',
|
64
|
+
'CI Neuquén' => '20',
|
65
|
+
'CI La Pampa' => '21',
|
66
|
+
'CI Río Negro' => '22',
|
67
|
+
'CI Santa Cruz' => '23',
|
68
|
+
'CI Tierra del Fuego' => '24' }
|
69
|
+
|
70
|
+
CURRENCY = { :peso => { :code => 'PES', :nombre => 'Pesos Argentinos' },
|
71
|
+
:dolar => { :code => 'DOL', :nombre => 'Dolar Estadounidense' },
|
72
|
+
:real => { :code => '012', :nombre => 'Real' },
|
73
|
+
:euro => { :code => '060', :nombre => 'Euro' },
|
74
|
+
:oro => { :code => '049', :nombre => 'Gramos de Oro Fino' } }
|
70
75
|
|
71
76
|
ALIC_IVA = { 0 => '3',
|
72
77
|
0.0 => '3',
|
@@ -82,5 +87,4 @@ module Snoopy
|
|
82
87
|
:nota_credito_a => '03',
|
83
88
|
:nota_credito_b => '08',
|
84
89
|
:nota_credito_c => '13' }
|
85
|
-
|
86
90
|
end
|
@@ -20,4 +20,15 @@ class Hash
|
|
20
20
|
def underscore_keys
|
21
21
|
dup.underscore_keys!
|
22
22
|
end unless method_defined?(:underscore_keys)
|
23
|
+
|
24
|
+
# Implement this method because only is supported by > Rails 4, so if you want use only ruby, this will help. :)
|
25
|
+
def deep_symbolize_keys
|
26
|
+
return self.reduce({}) do |memo, (k, v)|
|
27
|
+
memo.tap { |m| m[k.to_sym] = (v.is_a?(Hash) || v.is_a?(Array)) ? v.deep_symbolize_keys : v }
|
28
|
+
end if self.is_a? Hash
|
29
|
+
return self.reduce([]) do |memo, v|
|
30
|
+
memo << v.deep_symbolize_keys; memo
|
31
|
+
end if self.is_a? Array
|
32
|
+
self
|
33
|
+
end unless method_defined?(:deep_symbolize_keys)
|
23
34
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Snoopy
|
2
|
+
module Exception
|
3
|
+
|
4
|
+
class Exception < ::StandardError
|
5
|
+
attr_accessor :backtrace
|
6
|
+
|
7
|
+
def initialize(msg, backtrace)
|
8
|
+
@backtrace = backtrace
|
9
|
+
super(msg)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ClientError < Exception
|
14
|
+
def initialize(msj)
|
15
|
+
super(msj, nil)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ServerTimeout < Timeout::Error
|
20
|
+
end
|
21
|
+
|
22
|
+
module AuthenticationAdapter
|
23
|
+
end
|
24
|
+
|
25
|
+
module AuthorizeAdapter
|
26
|
+
class SetBillNumberParser < Exception
|
27
|
+
end
|
28
|
+
|
29
|
+
class BuildBodyRequest < Exception
|
30
|
+
end
|
31
|
+
|
32
|
+
class ObservationParser < Exception
|
33
|
+
end
|
34
|
+
|
35
|
+
class ErrorParser < Exception
|
36
|
+
end
|
37
|
+
|
38
|
+
class EventsParser < Exception
|
39
|
+
end
|
40
|
+
|
41
|
+
class FecaeSolicitarResultParser < Exception
|
42
|
+
end
|
43
|
+
|
44
|
+
class FecaeResponseParser < Exception
|
45
|
+
end
|
46
|
+
|
47
|
+
class FecompConsultResponseParser < Exception
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module Bill
|
52
|
+
# class NonExistAttributes < Exception
|
53
|
+
# def initialize(attributes, backtrace=nil)
|
54
|
+
# @backtrace = backtrace
|
55
|
+
# super("Non exist attributes: #{attributes}", backtrace)
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
class MissingAttributes < Exception
|
60
|
+
def initialize(attributes, backtrace=nil)
|
61
|
+
@backtrace = backtrace
|
62
|
+
super("Missing attributes: #{attributes}", backtrace)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class InvalidValueAttribute < Exception
|
67
|
+
def initialize(attribute, backtrace=nil)
|
68
|
+
@backtrace = backtrace
|
69
|
+
super("Invalid value for: #{attribute}", backtrace)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/snoopy_afip/version.rb
CHANGED