bank_api 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/bank_api.rb +8 -0
- data/lib/bank_api/clients/banco_de_chile_company_client.rb +102 -20
- data/lib/bank_api/clients/banco_security/company_client.rb +16 -0
- data/lib/bank_api/clients/banco_security/concerns/deposits.rb +1 -36
- data/lib/bank_api/clients/banco_security/concerns/session.rb +34 -0
- data/lib/bank_api/clients/banco_security/concerns/withdrawals.rb +109 -0
- data/lib/bank_api/clients/base_client.rb +28 -2
- data/lib/bank_api/clients/navigation/banco_security/company_navigation.rb +16 -0
- data/lib/bank_api/exceptions.rb +4 -1
- data/lib/bank_api/utils/banco_de_chile.rb +16 -0
- data/lib/bank_api/utils/banco_security.rb +6 -0
- data/lib/bank_api/values/withdrawal_entry.rb +18 -0
- data/lib/bank_api/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 824a1460fdfece4945b291da2398b9c9ef6d4860937dd91b294dbcbd90829478
|
4
|
+
data.tar.gz: 4cfdce182a2199b8df6125ca3761eb4f654cc5e6a631c48d378a5d9c7f5de5fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d35ca4393a0bf873515a6b4c8f40456d9a43191ad49e606589b77429f4c4a27f6c52349dba9d65e735b592e60bc7580fae91489acbfa5b7c4ae56a0bd40e315e
|
7
|
+
data.tar.gz: 22f355ac3a900204d633201a1000440f39d638a2e0b4b2010358af40efdc772f313d89adc6cc5655909cc2281c0db4e4197240a345ef9363df49ff321ef1cc09
|
data/Gemfile.lock
CHANGED
data/lib/bank_api.rb
CHANGED
@@ -25,6 +25,10 @@ module BankApi
|
|
25
25
|
Clients::BancoDeChileCompanyClient.new(configuration).get_recent_deposits(options)
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.get_bdc_recent_company_withdrawals
|
29
|
+
Clients::BancoDeChileCompanyClient.new(configuration).get_recent_withdrawals
|
30
|
+
end
|
31
|
+
|
28
32
|
def self.get_bdc_account_balance(options = {})
|
29
33
|
Clients::BancoDeChileCompanyClient.new(configuration).get_account_balance(options)
|
30
34
|
end
|
@@ -38,6 +42,10 @@ module BankApi
|
|
38
42
|
company_instance.get_recent_deposits(options)
|
39
43
|
end
|
40
44
|
|
45
|
+
def self.get_recent_company_withdrawals
|
46
|
+
company_instance.get_recent_withdrawals
|
47
|
+
end
|
48
|
+
|
41
49
|
def self.company_transfer(transfer_data)
|
42
50
|
company_instance.transfer(transfer_data)
|
43
51
|
end
|
@@ -2,13 +2,17 @@ require 'rest-client'
|
|
2
2
|
require 'timezone'
|
3
3
|
|
4
4
|
require 'bank_api/clients/base_client'
|
5
|
+
require 'bank_api/utils/banco_de_chile'
|
5
6
|
|
6
7
|
module BankApi::Clients
|
7
8
|
class BancoDeChileCompanyClient < BaseClient
|
8
9
|
COMPANY_LOGIN_URL = 'https://www.empresas.bancochile.cl/cgi-bin/navega?pagina=enlinea/login_fus'
|
9
10
|
COMPANY_DEPOSITS_URL = 'https://www.empresas.bancochile.cl/GlosaInternetEmpresaRecibida/ConsultaRecibidaAction.do'
|
11
|
+
COMPANY_WITHDRAWALS_URL = 'https://www.empresas.bancochile.cl/TefMasivasWEB/consulta.do?accion=consulta&vacio=0'
|
10
12
|
COMPANY_PREPARE_DEPOSITS_URL = 'https://www.empresas.bancochile.cl/GlosaInternetEmpresaRecibida/RespuestaConsultaRecibidaAction.do'
|
13
|
+
COMPANY_PREPARE_WITHDRAWALS_URL = 'https://www.empresas.bancochile.cl/TefMasivasWEB/consulta.do'
|
11
14
|
COMPANY_DEPOSITS_TXT_URL = 'https://www.empresas.bancochile.cl/GlosaInternetEmpresaRecibida/RespuestaConsultaRecibidaAction.do'
|
15
|
+
COMPANY_WITHDRAWALS_TXT_URL = 'https://www.empresas.bancochile.cl/TefMasivasWEB/consulta.do'
|
12
16
|
COMPANY_ACCOUNT_DEPOSITS_URL = 'https://www.empresas.bancochile.cl/CCOLSaldoMovimientosWEB/selectorCuentas.do?accion=initSelectorCuentas&cuenta=001642711701&moneda=CTD#page=page-1'
|
13
17
|
COMPANY_CC_BALANCE_URL = 'https://www.empresas.bancochile.cl/CCOLDerivadorWEB/selectorCuentas.do?accion=initSelectorCuentas&opcion=saldos&moduloProducto=CC'
|
14
18
|
|
@@ -89,6 +93,14 @@ module BankApi::Clients
|
|
89
93
|
browser.close
|
90
94
|
end
|
91
95
|
|
96
|
+
def get_withdrawals
|
97
|
+
login
|
98
|
+
|
99
|
+
get_withdrawals_from_transfers_section
|
100
|
+
ensure
|
101
|
+
browser.close
|
102
|
+
end
|
103
|
+
|
92
104
|
def get_deposits_from_balance_section
|
93
105
|
goto_account_deposits
|
94
106
|
account_deposits_from_txt
|
@@ -99,6 +111,11 @@ module BankApi::Clients
|
|
99
111
|
deposits_from_txt
|
100
112
|
end
|
101
113
|
|
114
|
+
def get_withdrawals_from_transfers_section
|
115
|
+
goto_withdrawals
|
116
|
+
withdrawals_from_txt
|
117
|
+
end
|
118
|
+
|
102
119
|
def login
|
103
120
|
goto_login_url
|
104
121
|
set_login_values
|
@@ -129,6 +146,10 @@ module BankApi::Clients
|
|
129
146
|
browser.goto COMPANY_DEPOSITS_URL
|
130
147
|
end
|
131
148
|
|
149
|
+
def goto_withdrawals
|
150
|
+
browser.goto COMPANY_WITHDRAWALS_URL
|
151
|
+
end
|
152
|
+
|
132
153
|
def account_deposits_from_txt
|
133
154
|
url = browser.search("#expoDato_child > a:nth-child(3)").attribute(:href)
|
134
155
|
result = browser.download(url)
|
@@ -147,12 +168,11 @@ module BankApi::Clients
|
|
147
168
|
prepare_deposits
|
148
169
|
response = RestClient::Request.execute(
|
149
170
|
url: COMPANY_DEPOSITS_TXT_URL, method: :post, headers: session_headers,
|
150
|
-
payload: deposits_txt_payload(
|
171
|
+
payload: deposits_txt_payload(date_range[:start], date_range[:end]), verify_ssl: true
|
151
172
|
)
|
152
173
|
raise "Banchile is down" if response.body.include? "no podemos atenderle"
|
153
|
-
|
154
|
-
transactions
|
155
|
-
format_transactions(transactions)
|
174
|
+
transactions = split_deposit_transactions(response.body)
|
175
|
+
format_deposit_transactions(transactions)
|
156
176
|
rescue => e
|
157
177
|
validate_banchile_status!
|
158
178
|
raise e
|
@@ -161,18 +181,43 @@ module BankApi::Clients
|
|
161
181
|
def prepare_deposits
|
162
182
|
RestClient::Request.execute(
|
163
183
|
url: COMPANY_PREPARE_DEPOSITS_URL, method: :post, headers: session_headers,
|
164
|
-
payload: prepare_deposits_payload(
|
184
|
+
payload: prepare_deposits_payload(date_range[:start], date_range[:end]),
|
165
185
|
verify_ssl: true
|
166
186
|
)
|
167
187
|
end
|
168
188
|
|
169
|
-
def
|
189
|
+
def withdrawals_from_txt
|
190
|
+
prepare_withdrawals
|
191
|
+
response = RestClient::Request.execute(
|
192
|
+
url: COMPANY_WITHDRAWALS_TXT_URL, method: :post, headers: session_headers,
|
193
|
+
payload: withdrawals_txt_payload(date_range[:start], date_range[:end])
|
194
|
+
)
|
195
|
+
raise "Banchile is down" if response.body.include? "no podemos atenderle"
|
196
|
+
transactions = split_withdrawal_transactions(response.body)
|
197
|
+
format_withdrawal_transactions(transactions)
|
198
|
+
rescue => e
|
199
|
+
validate_banchile_status!
|
200
|
+
raise e
|
201
|
+
end
|
202
|
+
|
203
|
+
def prepare_withdrawals
|
204
|
+
RestClient::Request.execute(
|
205
|
+
url: COMPANY_PREPARE_WITHDRAWALS_URL, method: :post, headers: session_headers,
|
206
|
+
payload: prepare_withdrawals_payload(date_range[:start], date_range[:end])
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
def split_deposit_transactions(transactions_str)
|
170
211
|
transactions_str.delete("\r").split("\n").drop(1).map { |r| r.split(";") }.select do |t|
|
171
212
|
t[7] == "Aprobada"
|
172
213
|
end
|
173
214
|
end
|
174
215
|
|
175
|
-
def
|
216
|
+
def split_withdrawal_transactions(transactions_str)
|
217
|
+
transactions_str.delete("\r").split("\n")
|
218
|
+
end
|
219
|
+
|
220
|
+
def format_deposit_transactions(transactions)
|
176
221
|
transactions.map do |t|
|
177
222
|
{
|
178
223
|
client: format_client_name(t[3]),
|
@@ -184,6 +229,18 @@ module BankApi::Clients
|
|
184
229
|
end
|
185
230
|
end
|
186
231
|
|
232
|
+
def format_withdrawal_transactions(transactions)
|
233
|
+
transactions.map do |t|
|
234
|
+
{
|
235
|
+
rut: Utils::BancoDeChile.format_rut(t[25..34]),
|
236
|
+
client: format_client_name(t[35..64].strip),
|
237
|
+
account_number: t[65..82].strip,
|
238
|
+
amount: t[93..103].to_i,
|
239
|
+
email: t[166..216].strip
|
240
|
+
}
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
187
244
|
def format_account_transactions(transactions)
|
188
245
|
transactions.inject([]) do |memo, t|
|
189
246
|
parts = t.split(";")
|
@@ -206,25 +263,50 @@ module BankApi::Clients
|
|
206
263
|
name.to_s.split("DE:").last.to_s.strip
|
207
264
|
end
|
208
265
|
|
209
|
-
def base_payload(from_date, to_date)
|
210
|
-
{
|
211
|
-
'initDate' => from_date,
|
212
|
-
'endDate' => to_date,
|
213
|
-
'ctaCorriente' => padded_account,
|
214
|
-
'nada' => 'nada'
|
215
|
-
}
|
216
|
-
end
|
217
|
-
|
218
266
|
def padded_account
|
219
267
|
"0" * (12 - @bdc_account.length) + @bdc_account
|
220
268
|
end
|
221
269
|
|
222
270
|
def prepare_deposits_payload(from_date, to_date)
|
223
|
-
|
271
|
+
base_deposits_payload(from_date, to_date).merge('accion' => 'buscarOperaciones')
|
224
272
|
end
|
225
273
|
|
226
274
|
def deposits_txt_payload(from_date, to_date)
|
227
|
-
|
275
|
+
base_deposits_payload(from_date, to_date).merge('accion' => 'exportarTxtOperaciones')
|
276
|
+
end
|
277
|
+
|
278
|
+
def prepare_withdrawals_payload(from_date, to_date)
|
279
|
+
base_withdrawals_payload(from_date, to_date).merge('accion' => 'consulta')
|
280
|
+
end
|
281
|
+
|
282
|
+
def withdrawals_txt_payload(from_date, to_date)
|
283
|
+
base_withdrawals_payload(from_date, to_date).merge('accion' => 'exportarTxt')
|
284
|
+
end
|
285
|
+
|
286
|
+
def base_deposits_payload(from_date, to_date)
|
287
|
+
{
|
288
|
+
'initDate' => from_date,
|
289
|
+
'endDate' => to_date,
|
290
|
+
'ctaCorriente' => padded_account,
|
291
|
+
'nada' => 'nada'
|
292
|
+
}
|
293
|
+
end
|
294
|
+
|
295
|
+
def base_withdrawals_payload(from_date, to_date)
|
296
|
+
{
|
297
|
+
"llavePre" => "",
|
298
|
+
"llaveIns" => "",
|
299
|
+
"rutIns" => "",
|
300
|
+
"pag" => "",
|
301
|
+
"campo" => "",
|
302
|
+
'initDate' => from_date,
|
303
|
+
'endDate' => to_date,
|
304
|
+
"cuentaCargo" => padded_account,
|
305
|
+
"destinatario" => "",
|
306
|
+
"operacion" => "",
|
307
|
+
"estado" => "12",
|
308
|
+
'nada' => 'nada'
|
309
|
+
}
|
228
310
|
end
|
229
311
|
|
230
312
|
def session_headers
|
@@ -254,8 +336,8 @@ module BankApi::Clients
|
|
254
336
|
selenium_browser.manage.cookie_named(name)[:value]
|
255
337
|
end
|
256
338
|
|
257
|
-
def
|
258
|
-
@
|
339
|
+
def date_range
|
340
|
+
@date_range ||= begin
|
259
341
|
timezone = Timezone['America/Santiago']
|
260
342
|
today = timezone.utc_to_local(Time.now).to_date
|
261
343
|
{ start: (today - @days_to_check).strftime("%d/%m/%Y"), end: today.strftime("%d/%m/%Y") }
|
@@ -5,7 +5,9 @@ require 'bank_api/clients/base_client'
|
|
5
5
|
require 'bank_api/clients/banco_security/concerns/balance'
|
6
6
|
require 'bank_api/clients/banco_security/concerns/deposits'
|
7
7
|
require 'bank_api/clients/banco_security/concerns/login'
|
8
|
+
require 'bank_api/clients/banco_security/concerns/session'
|
8
9
|
require 'bank_api/clients/banco_security/concerns/transfers'
|
10
|
+
require 'bank_api/clients/banco_security/concerns/withdrawals'
|
9
11
|
require 'bank_api/clients/navigation/banco_security/company_navigation'
|
10
12
|
require 'bank_api/utils/banco_security'
|
11
13
|
|
@@ -14,8 +16,10 @@ module BankApi::Clients::BancoSecurity
|
|
14
16
|
include BankApi::Clients::Navigation::BancoSecurity::CompanyNavigation
|
15
17
|
include BankApi::Clients::BancoSecurity::Balance
|
16
18
|
include BankApi::Clients::BancoSecurity::Deposits
|
19
|
+
include BankApi::Clients::BancoSecurity::Withdrawals
|
17
20
|
include BankApi::Clients::BancoSecurity::Transfers
|
18
21
|
include BankApi::Clients::BancoSecurity::Login
|
22
|
+
include BankApi::Clients::BancoSecurity::Session
|
19
23
|
|
20
24
|
def initialize(config = BankApi::Configuration.new)
|
21
25
|
@user_rut = config.banco_security.user_rut
|
@@ -52,6 +56,18 @@ module BankApi::Clients::BancoSecurity
|
|
52
56
|
browser.close
|
53
57
|
end
|
54
58
|
|
59
|
+
def get_withdrawals
|
60
|
+
login
|
61
|
+
goto_company_dashboard
|
62
|
+
goto_withdrawals
|
63
|
+
select_withdrawals_range
|
64
|
+
withdrawals = withdrawals_from_json
|
65
|
+
validate_withdrawals(withdrawals) unless withdrawals.empty?
|
66
|
+
withdrawals
|
67
|
+
ensure
|
68
|
+
browser.close
|
69
|
+
end
|
70
|
+
|
55
71
|
def execute_transfer(transfer_data)
|
56
72
|
login
|
57
73
|
goto_company_dashboard(transfer_data[:origin] || @company_rut)
|
@@ -3,8 +3,6 @@ require 'rest-client'
|
|
3
3
|
|
4
4
|
module BankApi::Clients::BancoSecurity
|
5
5
|
module Deposits
|
6
|
-
SESSION_VALIDATION = "https://www.bancosecurity.cl/empresas/SessionValidation.asp"
|
7
|
-
|
8
6
|
def select_deposits_range
|
9
7
|
browser.search('.BusquedaPorDefectoRecibida a:contains("búsqueda avanzada")').click
|
10
8
|
browser.search('#RadioEntreFechasRecibido').click
|
@@ -46,18 +44,6 @@ module BankApi::Clients::BancoSecurity
|
|
46
44
|
format_transactions(transactions)
|
47
45
|
end
|
48
46
|
|
49
|
-
def setup_authentication
|
50
|
-
response = RestClient::Request.execute(
|
51
|
-
url: SESSION_VALIDATION, method: :post, headers: session_headers
|
52
|
-
)
|
53
|
-
new_cookies = response.headers[:set_cookie].first.delete(" ").split(";").map do |a|
|
54
|
-
a.split("=")
|
55
|
-
end
|
56
|
-
new_cookies.each do |key, value|
|
57
|
-
selenium_browser.manage.add_cookie(name: key, value: value)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
47
|
def deposits_from_account_details
|
62
48
|
data = browser.download(
|
63
49
|
deposits_account_details_url
|
@@ -71,7 +57,7 @@ module BankApi::Clients::BancoSecurity
|
|
71
57
|
datetime = timezone.local_to_utc(DateTime.parse(t[0]))
|
72
58
|
{
|
73
59
|
client: t[1],
|
74
|
-
rut: format_rut(t[2]),
|
60
|
+
rut: Utils::BancoSecurity.format_rut(t[2]),
|
75
61
|
date: datetime.to_date,
|
76
62
|
time: datetime,
|
77
63
|
amount: t[5].to_i
|
@@ -110,21 +96,6 @@ module BankApi::Clients::BancoSecurity
|
|
110
96
|
end
|
111
97
|
end
|
112
98
|
|
113
|
-
def session_headers
|
114
|
-
{
|
115
|
-
"User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 " +
|
116
|
-
"(KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
|
117
|
-
"Accept" => "*/*",
|
118
|
-
"Cookie" => cookies
|
119
|
-
}
|
120
|
-
end
|
121
|
-
|
122
|
-
def cookies
|
123
|
-
selenium_browser.manage.all_cookies.map do |cookie|
|
124
|
-
"#{cookie[:name]}=#{cookie[:value]}"
|
125
|
-
end.join("; ")
|
126
|
-
end
|
127
|
-
|
128
99
|
def deposits_txt_url
|
129
100
|
selenium_browser.execute_script("console.log(DescargarDocumentoTxtRecibidas)")
|
130
101
|
log = selenium_browser.manage.logs.get(:browser).last
|
@@ -135,12 +106,6 @@ module BankApi::Clients::BancoSecurity
|
|
135
106
|
browser.search("a:contains('Descargar TXT')").first.attribute("href")
|
136
107
|
end
|
137
108
|
|
138
|
-
def format_rut(rut)
|
139
|
-
verification_digit = rut[-1]
|
140
|
-
without_verification_digit = rut[0..-2].reverse.scan(/.{1,3}/).join(".").reverse
|
141
|
-
"#{without_verification_digit}-#{verification_digit}"
|
142
|
-
end
|
143
|
-
|
144
109
|
def total_deposits
|
145
110
|
pages_info = wait(".k-pager-info")
|
146
111
|
matches = pages_info.text.match(/(\d+)[a-z\s-]+(\d+)[a-z\s-]+(\d+)/)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module BankApi::Clients::BancoSecurity
|
4
|
+
module Session
|
5
|
+
SESSION_VALIDATION = "https://www.bancosecurity.cl/empresas/SessionValidation.asp"
|
6
|
+
|
7
|
+
def setup_authentication
|
8
|
+
response = RestClient::Request.execute(
|
9
|
+
url: SESSION_VALIDATION, method: :post, headers: session_headers
|
10
|
+
)
|
11
|
+
new_cookies = response.headers[:set_cookie].first.delete(" ").split(";").map do |a|
|
12
|
+
a.split("=")
|
13
|
+
end
|
14
|
+
new_cookies.each do |key, value|
|
15
|
+
selenium_browser.manage.add_cookie(name: key, value: value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def session_headers
|
20
|
+
{
|
21
|
+
"User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 " +
|
22
|
+
"(KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
|
23
|
+
"Accept" => "*/*",
|
24
|
+
"Cookie" => cookies
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def cookies
|
29
|
+
selenium_browser.manage.all_cookies.map do |cookie|
|
30
|
+
"#{cookie[:name]}=#{cookie[:value]}"
|
31
|
+
end.join("; ")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module BankApi::Clients::BancoSecurity
|
4
|
+
module Withdrawals
|
5
|
+
WITHDRAWALS_URL = 'https://www.bancosecurity.cl/ConvivenciaEmpresas/CartolasTEF/Home/ConsultarEnviadasEmpresas'
|
6
|
+
|
7
|
+
def select_withdrawals_range
|
8
|
+
browser.search('.BusquedaPorDefectoEnv a:contains("búsqueda avanzada")').click
|
9
|
+
browser.search('#RadioEntreFechasEnviadoE').click
|
10
|
+
fill_withdrawal_date_inputs
|
11
|
+
wait('.ContenedorSubmitEnviadas .btn_buscar').click
|
12
|
+
wait_for_withdrawals_fetch
|
13
|
+
end
|
14
|
+
|
15
|
+
def fill_withdrawal_date_inputs
|
16
|
+
start_element = browser.search('#datePickerInicioEnviadoE').elements.first
|
17
|
+
start_element.send_key "-"
|
18
|
+
withdrawal_range[:start].strftime('%d%m%Y').chars.each do |c|
|
19
|
+
start_element.send_key c
|
20
|
+
sleep 0.1
|
21
|
+
end
|
22
|
+
end_element = browser.search('#datePickerFinEnviadoE').elements.first
|
23
|
+
end_element.send_key "-"
|
24
|
+
withdrawal_range[:end].strftime('%d%m%Y').chars.each do |c|
|
25
|
+
end_element.send_key c
|
26
|
+
sleep 0.1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def wait_for_withdrawals_fetch
|
31
|
+
goto_frame query: '#mainFrame'
|
32
|
+
goto_frame query: 'iframe[name="central"]', should_reset: false
|
33
|
+
wait('.k-loading-image') { browser.search('.k-loading-image').none? }
|
34
|
+
end
|
35
|
+
|
36
|
+
def withdrawals_from_json
|
37
|
+
raise BankApi::Withdrawal::FetchError, "Couldn't fetch withdrawals" unless any_withdrawals?
|
38
|
+
setup_authentication
|
39
|
+
response = RestClient::Request.execute(
|
40
|
+
url: WITHDRAWALS_URL, method: :post, headers: session_headers,
|
41
|
+
payload: withdrawals_payload(deposit_range[:start], deposit_range[:end])
|
42
|
+
)
|
43
|
+
transactions = JSON.parse(response.body)["Items"]
|
44
|
+
format_withdrawal_transactions(transactions)
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_withdrawal_transactions(transactions)
|
48
|
+
transactions.map do |t|
|
49
|
+
datetime = Time.at(t["Fecha"].match(/(\d+)/)[0].to_i / 1000).utc
|
50
|
+
{
|
51
|
+
client: t["NombreDestino"],
|
52
|
+
account_bank: t["BancoDestino"],
|
53
|
+
account_number: t["CuentaDestino"],
|
54
|
+
rut: Utils::BancoSecurity.format_rut(t["RutDestino"]),
|
55
|
+
email: t["MailDestino"],
|
56
|
+
date: datetime.to_date,
|
57
|
+
time: datetime,
|
58
|
+
amount: t["Monto"],
|
59
|
+
trx_id: t["NumeroTransaccion"]
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def withdrawals_payload(start_date, end_date)
|
65
|
+
{
|
66
|
+
"parametro" => "", "numeroCuenta" => account_number_variable, "monto" => 0, "opcion" => "",
|
67
|
+
"fechaInicio" => "#{start_date} 0:00:00", "fechaFin" => "#{end_date} 0:00:00",
|
68
|
+
"estado" => 1, "tipoTransaccion" => "", "take" => 1000, "skip" => 0, "page" => 1,
|
69
|
+
"pageSize" => 1000, "sort[0][field]" => "Fecha", "sort[0][dir]" => "desc"
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def withdrawal_range
|
74
|
+
@withdrawal_range ||= begin
|
75
|
+
timezone = Timezone['America/Santiago']
|
76
|
+
today = timezone.utc_to_local(Time.now).to_date
|
77
|
+
{ start: (today - @days_to_check), end: today }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def total_withdrawals
|
82
|
+
pages_info = wait(".k-pager-info")
|
83
|
+
matches = pages_info.text.match(/(\d+)[a-z\s-]+(\d+)[a-z\s-]+(\d+)/)
|
84
|
+
matches[3].to_i
|
85
|
+
end
|
86
|
+
|
87
|
+
def any_withdrawals?
|
88
|
+
browser.search(
|
89
|
+
"#gridPrincipalEnviadasE " \
|
90
|
+
".k-label:contains('No se han encontrado transacciones para la búsqueda seleccionada.')"
|
91
|
+
).none?
|
92
|
+
end
|
93
|
+
|
94
|
+
def account_number_variable
|
95
|
+
selenium_browser.manage.logs.get(:browser).last
|
96
|
+
selenium_browser.execute_script("console.log(nCuenta)")
|
97
|
+
log = selenium_browser.manage.logs.get(:browser).last
|
98
|
+
/\"(.*)\"/.match(log.message).captures.first
|
99
|
+
end
|
100
|
+
|
101
|
+
def validate_withdrawals(withdrawals)
|
102
|
+
total_withdrawals_ = total_withdrawals
|
103
|
+
unless withdrawals.count == total_withdrawals_
|
104
|
+
raise BankApi::Withdrawal::QuantityError, "Expected #{total_withdrawals_} withdrawals," +
|
105
|
+
" got #{withdrawals.count}."
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -4,6 +4,7 @@ require 'selenium-webdriver'
|
|
4
4
|
require 'bank_api/exceptions'
|
5
5
|
require 'bank_api/sign_deposits'
|
6
6
|
require 'bank_api/values/deposit_entry'
|
7
|
+
require 'bank_api/values/withdrawal_entry'
|
7
8
|
|
8
9
|
module BankApi::Clients
|
9
10
|
class BaseClient
|
@@ -13,7 +14,7 @@ module BankApi::Clients
|
|
13
14
|
|
14
15
|
def get_recent_deposits(options = {})
|
15
16
|
validate_credentials
|
16
|
-
|
17
|
+
parse_deposit_entries(get_deposits(options))
|
17
18
|
end
|
18
19
|
|
19
20
|
def get_account_balance(options)
|
@@ -21,6 +22,11 @@ module BankApi::Clients
|
|
21
22
|
get_balance(options)
|
22
23
|
end
|
23
24
|
|
25
|
+
def get_recent_withdrawals
|
26
|
+
validate_credentials
|
27
|
+
parse_withdrawal_entries(get_withdrawals)
|
28
|
+
end
|
29
|
+
|
24
30
|
def transfer(transfer_data)
|
25
31
|
validate_credentials
|
26
32
|
validate_transfer_missing_data(transfer_data)
|
@@ -55,6 +61,10 @@ module BankApi::Clients
|
|
55
61
|
raise NotImplementedError
|
56
62
|
end
|
57
63
|
|
64
|
+
def get_withdrawals
|
65
|
+
raise NotImplementedError
|
66
|
+
end
|
67
|
+
|
58
68
|
def validate_transfer_missing_data(_transfer_data)
|
59
69
|
raise NotImplementedError
|
60
70
|
end
|
@@ -126,7 +136,7 @@ module BankApi::Clients
|
|
126
136
|
browser.goto(frame: frame)
|
127
137
|
end
|
128
138
|
|
129
|
-
def
|
139
|
+
def parse_deposit_entries(entries)
|
130
140
|
deposit_entries = entries.map do |entry|
|
131
141
|
BankApi::Values::DepositEntry.new(
|
132
142
|
entry[:amount],
|
@@ -139,5 +149,21 @@ module BankApi::Clients
|
|
139
149
|
end
|
140
150
|
BankApi::SignDeposits.sign(deposit_entries)
|
141
151
|
end
|
152
|
+
|
153
|
+
def parse_withdrawal_entries(entries)
|
154
|
+
entries.map do |entry|
|
155
|
+
BankApi::Values::WithdrawalEntry.new(
|
156
|
+
entry[:amount],
|
157
|
+
entry[:date],
|
158
|
+
entry[:time],
|
159
|
+
entry[:rut],
|
160
|
+
entry[:client],
|
161
|
+
entry[:account_number],
|
162
|
+
entry[:account_bank],
|
163
|
+
entry[:trx_id],
|
164
|
+
bank_name
|
165
|
+
)
|
166
|
+
end
|
167
|
+
end
|
142
168
|
end
|
143
169
|
end
|
@@ -71,6 +71,22 @@ module BankApi::Clients::Navigation
|
|
71
71
|
wait("a.clickable:contains(\"#{account_number}\")").click
|
72
72
|
end
|
73
73
|
|
74
|
+
def goto_withdrawals
|
75
|
+
goto_frame query: '#topFrame'
|
76
|
+
selenium_browser.execute_script(
|
77
|
+
"MM_goToURL('parent.frames[\\'topFrame\\']','../menu/MenuTopTransferencias.asp'," +
|
78
|
+
"'parent.frames[\\'leftFrame\\']','../menu/MenuTransferencias.asp'," +
|
79
|
+
"'parent.frames[\\'mainFrame\\']','../../../noticias/transferencias.asp');"
|
80
|
+
)
|
81
|
+
selenium_browser.execute_script(
|
82
|
+
"MM_goToURL('parent.frames[\\'mainFrame\\']'," +
|
83
|
+
"'/empresas/RedirectConvivencia.asp?urlRedirect=CartolasTEF/Home/Index')"
|
84
|
+
)
|
85
|
+
goto_frame query: '#mainFrame'
|
86
|
+
goto_frame query: 'iframe[name="central"]', should_reset: false
|
87
|
+
wait('a.k-link:contains("Enviadas")').click
|
88
|
+
end
|
89
|
+
|
74
90
|
def goto_transfer_form
|
75
91
|
goto_frame query: '#topFrame'
|
76
92
|
selenium_browser.execute_script(
|
data/lib/bank_api/exceptions.rb
CHANGED
@@ -7,7 +7,10 @@ module BankApi
|
|
7
7
|
module Deposit
|
8
8
|
class FetchError < StandardError; end
|
9
9
|
class QuantityError < StandardError; end
|
10
|
-
|
10
|
+
end
|
11
|
+
module Withdrawal
|
12
|
+
class FetchError < StandardError; end
|
13
|
+
class QuantityError < StandardError; end
|
11
14
|
end
|
12
15
|
module Transfer
|
13
16
|
class InvalidBank < StandardError; end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Utils
|
2
|
+
module BancoDeChile
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def unpad_zeroes(string)
|
6
|
+
/0*(.*)/.match(string).captures.first
|
7
|
+
end
|
8
|
+
|
9
|
+
def format_rut(rut)
|
10
|
+
rut_ = unpad_zeroes(rut)
|
11
|
+
verification_digit = rut_[-1]
|
12
|
+
without_verification_digit = rut_[0..-2].reverse.scan(/.{1,3}/).join(".").reverse
|
13
|
+
"#{without_verification_digit}-#{verification_digit}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -45,5 +45,11 @@ module Utils
|
|
45
45
|
def valid_account_types
|
46
46
|
ACCOUNT_TYPES.keys.sort
|
47
47
|
end
|
48
|
+
|
49
|
+
def format_rut(rut)
|
50
|
+
verification_digit = rut[-1]
|
51
|
+
without_verification_digit = rut[0..-2].reverse.scan(/.{1,3}/).join(".").reverse
|
52
|
+
"#{without_verification_digit}-#{verification_digit}"
|
53
|
+
end
|
48
54
|
end
|
49
55
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module BankApi::Values
|
2
|
+
class WithdrawalEntry
|
3
|
+
attr_accessor :amount, :date, :time, :rut, :client, :account_number, :account_bank, :trx_id,
|
4
|
+
:bank
|
5
|
+
|
6
|
+
def initialize(amount, date, time, rut, client, account_number, account_bank, trx_id, bank)
|
7
|
+
@amount = amount
|
8
|
+
@date = date
|
9
|
+
@time = time
|
10
|
+
@rut = rut
|
11
|
+
@client = client
|
12
|
+
@account_number = account_number
|
13
|
+
@account_bank = account_bank
|
14
|
+
@trx_id = trx_id
|
15
|
+
@bank = bank
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/bank_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bank_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- oaestay
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pincers
|
@@ -163,16 +163,20 @@ files:
|
|
163
163
|
- lib/bank_api/clients/banco_security/concerns/balance.rb
|
164
164
|
- lib/bank_api/clients/banco_security/concerns/deposits.rb
|
165
165
|
- lib/bank_api/clients/banco_security/concerns/login.rb
|
166
|
+
- lib/bank_api/clients/banco_security/concerns/session.rb
|
166
167
|
- lib/bank_api/clients/banco_security/concerns/transfers.rb
|
168
|
+
- lib/bank_api/clients/banco_security/concerns/withdrawals.rb
|
167
169
|
- lib/bank_api/clients/base_client.rb
|
168
170
|
- lib/bank_api/clients/navigation/banco_security/company_navigation.rb
|
169
171
|
- lib/bank_api/configs/banco_security.rb
|
170
172
|
- lib/bank_api/configuration.rb
|
171
173
|
- lib/bank_api/exceptions.rb
|
172
174
|
- lib/bank_api/sign_deposits.rb
|
175
|
+
- lib/bank_api/utils/banco_de_chile.rb
|
173
176
|
- lib/bank_api/utils/banco_security.rb
|
174
177
|
- lib/bank_api/values/deposit_entry.rb
|
175
178
|
- lib/bank_api/values/dynamic_card.rb
|
179
|
+
- lib/bank_api/values/withdrawal_entry.rb
|
176
180
|
- lib/bank_api/version.rb
|
177
181
|
homepage: https://github.com/platanus/bank-api-gem
|
178
182
|
licenses:
|
@@ -194,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
198
|
version: '0'
|
195
199
|
requirements: []
|
196
200
|
rubyforge_project:
|
197
|
-
rubygems_version: 2.7.
|
201
|
+
rubygems_version: 2.7.7
|
198
202
|
signing_key:
|
199
203
|
specification_version: 4
|
200
204
|
summary: Wrapper for chilean banks
|