bank_api 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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