bank_api 0.3.4 → 0.4.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
  SHA256:
3
- metadata.gz: bc730d3ccd3df5e99abf8d49ef0df61a100ec2bf5d2abe349c15a2eb85251f23
4
- data.tar.gz: 5b51badad99fe9db5f0c72809d022aeabf8fec712522ba453f2c124a4d6a6f3d
3
+ metadata.gz: 165cb735e2871a94d6767c41ba7fe0ad18e5dfe81dab404fb997f2881eefc279
4
+ data.tar.gz: 49431a70b4e18686ac0c2a600233493266f7d7cd2e41531424bedacf29a65e4b
5
5
  SHA512:
6
- metadata.gz: 27bed8041370135108fa1892796b2eaccc7682a7acf5f97c7cc6dd69b069e7cad4592d98b44aadf0efc3fb34a1310e37e7b070160d69cfc21581c983d4be4434
7
- data.tar.gz: 416495f81f5c24ab408e11c1ed06694ea14474582b99706a17ba9d46edb05a216657254bda14ccba2f218dfe4e3a92ed40ac3c375c399883befa7765c0db1073
6
+ metadata.gz: b6098dd8ae93f1bf1c90494550ae8261d9cbe317d03201c740abca1984f52041bffa5a4e311bc84fb9be985647163caf6ad8e875d23585bb81aa03bb6823f354
7
+ data.tar.gz: d9b825d50ed7ad44fe5c95ee8913138c77f1a10546388aa766221a847662aed4c2b393cb2426d1306d697cbc904fc533269d7b4630c7e735d976a588e7c7aa76
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bank_api (0.3.4)
4
+ bank_api (0.4.0)
5
5
  pincers
6
+ rest-client
6
7
  timezone (~> 1.0)
7
8
 
8
9
  GEM
@@ -13,10 +14,18 @@ GEM
13
14
  ffi (~> 1.0, >= 1.0.11)
14
15
  coderay (1.1.2)
15
16
  diff-lcs (1.3)
16
- ffi (1.9.23)
17
+ domain_name (0.5.20180417)
18
+ unf (>= 0.0.5, < 1.0.0)
19
+ ffi (1.9.25)
20
+ http-cookie (1.0.3)
21
+ domain_name (~> 0.5)
17
22
  method_source (0.9.0)
23
+ mime-types (3.1)
24
+ mime-types-data (~> 3.2015)
25
+ mime-types-data (3.2016.0521)
18
26
  mini_portile2 (2.3.0)
19
- nokogiri (1.8.2)
27
+ netrc (0.11.0)
28
+ nokogiri (1.8.4)
20
29
  mini_portile2 (~> 2.3.0)
21
30
  pincers (0.7.12)
22
31
  nokogiri (~> 1.6)
@@ -28,6 +37,10 @@ GEM
28
37
  byebug (~> 10.0)
29
38
  pry (~> 0.10)
30
39
  rake (10.5.0)
40
+ rest-client (2.0.2)
41
+ http-cookie (>= 1.0.2, < 2.0)
42
+ mime-types (>= 1.16, < 4.0)
43
+ netrc (~> 0.8)
31
44
  rspec (3.7.0)
32
45
  rspec-core (~> 3.7.0)
33
46
  rspec-expectations (~> 3.7.0)
@@ -46,8 +59,11 @@ GEM
46
59
  childprocess (~> 0.5)
47
60
  rubyzip (~> 1.0)
48
61
  websocket (~> 1.0)
49
- timezone (1.2.11)
50
- websocket (1.2.5)
62
+ timezone (1.2.12)
63
+ unf (0.1.4)
64
+ unf_ext
65
+ unf_ext (0.0.7.5)
66
+ websocket (1.2.8)
51
67
 
52
68
  PLATFORMS
53
69
  ruby
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.require_paths = ["lib"]
23
23
 
24
24
  spec.add_dependency 'pincers'
25
+ spec.add_dependency 'rest-client'
25
26
  spec.add_dependency 'timezone', '~> 1.0'
26
27
 
27
28
  spec.add_development_dependency "bundler", "~> 1.16"
@@ -26,6 +26,10 @@ module BankApi
26
26
  end
27
27
 
28
28
  module BancoSecurity
29
+ def self.get_account_balance(account_number)
30
+ Clients::BancoSecurity::CompanyClient.new(BankApi.configuration).get_balance(account_number)
31
+ end
32
+
29
33
  def self.get_recent_company_deposits
30
34
  Clients::BancoSecurity::CompanyClient.new(BankApi.configuration).get_recent_deposits
31
35
  end
@@ -1,3 +1,4 @@
1
+ require 'rest-client'
1
2
  require 'timezone'
2
3
 
3
4
  require 'bank_api/clients/base_client'
@@ -6,8 +7,7 @@ module BankApi::Clients
6
7
  class BancoDeChileCompanyClient < BaseClient
7
8
  COMPANY_LOGIN_URL = 'https://www.empresas.bancochile.cl/cgi-bin/navega?pagina=enlinea/login_fus'
8
9
  COMPANY_DEPOSITS_URL = 'https://www.empresas.bancochile.cl/GlosaInternetEmpresaRecibida/ConsultaRecibidaAction.do'
9
-
10
- TABLE_OFFSET = 1
10
+ COMPANY_DEPOSITS_TXT_URL = 'https://www.empresas.bancochile.cl/GlosaInternetEmpresaRecibida/RespuestaConsultaRecibidaAction.do'
11
11
 
12
12
  DATE_COLUMN = 0
13
13
  RUT_COLUMN = 4
@@ -39,18 +39,11 @@ module BankApi::Clients
39
39
 
40
40
  def get_deposits
41
41
  login
42
- deposits_first_try = get_deposits_try
43
- deposits_second_try = get_deposits_try
44
- deposits_first_try == deposits_second_try ? deposits_first_try : []
45
- ensure
46
- browser.close
47
- end
48
-
49
- def get_deposits_try
50
42
  goto_deposits
51
43
  select_deposits_range
52
- submit_deposits_form
53
- extract_deposits_from_html
44
+ deposits = deposits_from_txt
45
+ browser.close
46
+ deposits
54
47
  end
55
48
 
56
49
  def login
@@ -80,14 +73,7 @@ module BankApi::Clients
80
73
  end
81
74
 
82
75
  def select_deposits_range
83
- timezone = Timezone['America/Santiago']
84
- range_start = (
85
- timezone.utc_to_local(Time.now).to_date - @days_to_check
86
- ).strftime("%d/%m/%Y")
87
- browser.search('input[name=initDate]').set(range_start)
88
- end
89
-
90
- def submit_deposits_form
76
+ browser.search('input[name=initDate]').set(deposit_range[:start])
91
77
  browser.search('#consultar').click
92
78
  end
93
79
 
@@ -95,46 +81,69 @@ module BankApi::Clients
95
81
  browser.search('table#sin_datos').count.zero?
96
82
  end
97
83
 
98
- def extract_deposits_from_html
99
- deposits = []
100
-
101
- return deposits unless any_deposits?
84
+ def total_results
85
+ browser.search("#pager .encabezadotabla:contains(\"Operaciones encontradas\")")
86
+ .text[/\d+/].to_i
87
+ end
102
88
 
103
- deposits += deposits_from_page
89
+ def deposits_from_txt
90
+ return [] unless any_deposits?
91
+ response = RestClient.post(
92
+ COMPANY_DEPOSITS_TXT_URL,
93
+ deposits_params(deposit_range[:start], deposit_range[:end]),
94
+ session_headers
95
+ )
96
+ transactions = split_transactions(response.body)
97
+ format_transactions(transactions)
98
+ end
104
99
 
105
- ((total_results - 1) / 10).times do
106
- goto_next_page
107
- deposits += deposits_from_page
100
+ def split_transactions(transactions_str)
101
+ transactions_str.delete("\r").split("\n").drop(1).map { |r| r.split(";") }.select do |t|
102
+ t[STATE_COLUMN] == "Aprobada"
108
103
  end
104
+ end
109
105
 
110
- deposits.sort_by { |d| d[:date] }
111
- end
112
-
113
- def deposits_from_page
114
- deposits = []
115
- deposit = {}
116
- browser.search('.linea1tabla').each_with_index do |div, index|
117
- if ((index - TABLE_OFFSET) % NUMBER_OF_COLUMNS) == RUT_COLUMN
118
- deposit[:rut] = div.text
119
- elsif ((index - TABLE_OFFSET) % NUMBER_OF_COLUMNS) == DATE_COLUMN
120
- deposit[:date] = Date.parse div.text
121
- elsif ((index - TABLE_OFFSET) % NUMBER_OF_COLUMNS) == AMOUNT_COLUMN
122
- deposit[:amount] = div.text.delete(',')
123
- elsif ((index - TABLE_OFFSET) % NUMBER_OF_COLUMNS) == STATE_COLUMN
124
- deposits << deposit if div.text == 'Aprobada'
125
- deposit = {}
126
- end
106
+ def format_transactions(transactions)
107
+ transactions.map do |t|
108
+ {
109
+ rut: t[RUT_COLUMN],
110
+ date: Date.parse(t[DATE_COLUMN]),
111
+ amount: t[AMOUNT_COLUMN].to_i
112
+ }
127
113
  end
128
- deposits
129
114
  end
130
115
 
131
- def goto_next_page
132
- browser.search("#pager .next").click
116
+ def deposits_params(from_date, to_date)
117
+ {
118
+ 'accion' => 'exportarTxtOperaciones',
119
+ 'initDate' => from_date,
120
+ 'endDate' => to_date,
121
+ 'ctaCorriente' => 'TODAS',
122
+ 'nada' => 'nada'
123
+ }
133
124
  end
134
125
 
135
- def total_results
136
- browser.search("#pager .encabezadotabla:contains(\"Operaciones encontradas\")")
137
- .text[/\d+/].to_i
126
+ def session_headers
127
+ {
128
+ "Cookie" => "JSESSIONID=#{cookie('JSESSIONID')}; token=#{cookie('token')}",
129
+ "Content-Type" => "application/x-www-form-urlencoded",
130
+ "Accept" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/" +
131
+ "apng,*/*;q=0.8",
132
+ "Referer" => "https://www.empresas.bancochile.cl/GlosaInternetEmpresaRecibida/" +
133
+ "RespuestaConsultaRecibidaAction.do"
134
+ }
135
+ end
136
+
137
+ def cookie(name)
138
+ selenium_browser.manage.cookie_named(name)[:value]
139
+ end
140
+
141
+ def deposit_range
142
+ @deposit_range ||= begin
143
+ timezone = Timezone['America/Santiago']
144
+ today = timezone.utc_to_local(Time.now).to_date
145
+ { start: (today - @days_to_check).strftime("%d/%m/%Y"), end: today.strftime("%d/%m/%Y") }
146
+ end
138
147
  end
139
148
  end
140
149
  end
@@ -2,6 +2,7 @@ require 'cgi'
2
2
  require 'timezone'
3
3
 
4
4
  require 'bank_api/clients/base_client'
5
+ require 'bank_api/clients/banco_security/concerns/balance'
5
6
  require 'bank_api/clients/banco_security/concerns/deposits'
6
7
  require 'bank_api/clients/banco_security/concerns/login'
7
8
  require 'bank_api/clients/banco_security/concerns/transfers'
@@ -11,6 +12,7 @@ require 'bank_api/utils/banco_security'
11
12
  module BankApi::Clients::BancoSecurity
12
13
  class CompanyClient < BankApi::Clients::BaseClient
13
14
  include BankApi::Clients::Navigation::BancoSecurity::CompanyNavigation
15
+ include BankApi::Clients::BancoSecurity::Balance
14
16
  include BankApi::Clients::BancoSecurity::Deposits
15
17
  include BankApi::Clients::BancoSecurity::Transfers
16
18
  include BankApi::Clients::BancoSecurity::Login
@@ -28,6 +30,13 @@ module BankApi::Clients::BancoSecurity
28
30
  :security
29
31
  end
30
32
 
33
+ def get_balance(account_number)
34
+ login
35
+ goto_company_dashboard
36
+ goto_balance
37
+ find_account_balance(account_number)
38
+ end
39
+
31
40
  def get_deposits
32
41
  login
33
42
  goto_company_dashboard
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+
3
+ module BankApi::Clients::BancoSecurity
4
+ module Balance
5
+ ACCOUNT_NUMBER_COLUMN = 0
6
+ AVAILABLE_BALANCE_COLUMN = 1
7
+ COUNTABLE_BALANCE_COLUMN = 2
8
+
9
+ def find_account_balance(account_number)
10
+ balance = browser.search(".cuentas-corrientes").search("tbody tr").map do |row|
11
+ cells = row.search("td")
12
+ {
13
+ account_number: cells[ACCOUNT_NUMBER_COLUMN].text,
14
+ available_balance: money_to_i(cells[AVAILABLE_BALANCE_COLUMN].text),
15
+ countable_balance: money_to_i(cells[COUNTABLE_BALANCE_COLUMN].text)
16
+ }
17
+ end.find do |row|
18
+ row[:account_number] == account_number
19
+ end
20
+ validate_balance(balance, account_number)
21
+ balance
22
+ end
23
+
24
+ def money_to_i(text)
25
+ text.delete(".").delete("$").delete(" ").to_i
26
+ end
27
+
28
+ def validate_balance(balance, account_number)
29
+ if balance.nil?
30
+ raise BankApi::Balance::InvalidAccountNumber, "Couldn't find balance of account " +
31
+ account_number.to_s
32
+ end
33
+ end
34
+ end
35
+ end
@@ -50,6 +50,23 @@ module BankApi::Clients::Navigation
50
50
  wait('a.k-link:contains("Recibidas")').click
51
51
  end
52
52
 
53
+ def goto_balance
54
+ goto_frame query: '#topFrame'
55
+ selenium_browser.execute_script(
56
+ "MM_goToURL('parent.frames[\\'topFrame\\']','../menu/MenuTopInicio.asp'," +
57
+ "'parent.frames[\\'leftFrame\\']','../menu/MenuInicio.asp'," +
58
+ "'parent.frames[\\'mainFrame\\']','../../../noticias/arriba_noticias.asp');" +
59
+ "return document.MM_returnValue;"
60
+ )
61
+ selenium_browser.execute_script(
62
+ "MM_goToURL('parent.frames[\\'mainFrame\\']'," +
63
+ "'/empresas/RedirectConvivencia.asp?urlRedirect" +
64
+ "=Cartola/Home/CartolaOrSaldoCuentaCorriente')"
65
+ )
66
+ goto_frame query: '#mainFrame'
67
+ goto_frame query: 'iframe[name="central"]', should_reset: false
68
+ end
69
+
53
70
  def goto_transfer_form
54
71
  goto_frame query: '#topFrame'
55
72
  selenium_browser.execute_script(
@@ -1,5 +1,8 @@
1
1
  module BankApi
2
2
  class MissingCredentialsError < StandardError; end
3
+ module Balance
4
+ class InvalidAccountNumber < StandardError; end
5
+ end
3
6
  module Deposit
4
7
  class QuantityError < StandardError; end
5
8
  class PaginationError < StandardError; end
@@ -1,3 +1,3 @@
1
1
  module BankApi
2
- VERSION = "0.3.4"
2
+ VERSION = "0.4.0"
3
3
  end
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: 0.3.4
4
+ version: 0.4.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-07-16 00:00:00.000000000 Z
11
+ date: 2018-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pincers
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: timezone
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -131,6 +145,7 @@ files:
131
145
  - lib/bank_api.rb
132
146
  - lib/bank_api/clients/banco_de_chile_company_client.rb
133
147
  - lib/bank_api/clients/banco_security/company_client.rb
148
+ - lib/bank_api/clients/banco_security/concerns/balance.rb
134
149
  - lib/bank_api/clients/banco_security/concerns/deposits.rb
135
150
  - lib/bank_api/clients/banco_security/concerns/login.rb
136
151
  - lib/bank_api/clients/banco_security/concerns/transfers.rb