abank 0.2.5 → 0.3.1

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.
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Abank
4
+ # acesso a base dados abank no bigquery
5
+ class Big
6
+ DF = '%Y-%m-%d'
7
+
8
+ # @return [Integer] contrato arrendamento em tratamento
9
+ attr_reader :ctpos
10
+
11
+ # (see CLI#criact)
12
+ def ct_cria
13
+ unless ct_existe?
14
+ dml("insert into #{BD}.re #{sql_contrato_mv}")
15
+ puts("CONTRATO #{opcao[:c]} #{bqnrs.zero? ? 'NAO ' : ''}INSERIDO")
16
+ end
17
+ # processar rendas sim/nao?
18
+ return unless bqnrs.positive? && opcao[:t]
19
+
20
+ # processa rendas associadas ao contrato arrendamento
21
+ ct_dados.re_insert
22
+ end
23
+
24
+ # @return [Boolean] contrato arrendamento ja existe sim/nao?
25
+ def ct_existe?
26
+ @ctlct = [{ ct: opcao[:c] }]
27
+ vaz = sql("select ct from #{BD}.re where ct in(#{str_lc}) and cnt=0").empty?
28
+ unless vaz
29
+ @bqnrs = 1
30
+ puts('CONTRATO JA EXISTE')
31
+ end
32
+ !vaz
33
+ end
34
+
35
+ # (see CLI#apagact)
36
+ def ct_apaga
37
+ @ctlct = [{ ct: opcao[:c] }]
38
+ re_delete_dml
39
+ end
40
+
41
+ # optem lista dados contrato arrendamento (inclui lista movimentos novos)
42
+ #
43
+ # @return [Big] acesso a base dados abank no bigquery
44
+ def ct_dados
45
+ ctlct.map! do |ctr|
46
+ opcao[:c] = ctr[:ct]
47
+ lre = sql(sql_last_re)[0]
48
+ ctr.merge(lre, mv: sql(sql_novo_mv(lre[:dl])))
49
+ end
50
+ self
51
+ end
52
+
53
+ # @param [Array] are lista rendas novas atual
54
+ # @return [Array<String>] lista rendas novas duma lista contratos arrendamento
55
+ def ct_rendas(lre = [])
56
+ while ctpos < ctlct.size
57
+ @mvpos = 0
58
+ lre += re_rendas
59
+ @ctpos += 1
60
+ end
61
+ lre
62
+ end
63
+
64
+ # @example sem dados movimentos
65
+ # [{ ct: 'r03000' }, ...]
66
+ # @example com dados movimentos
67
+ # [{ct: 'r03000', dc: '2020-03-01', ano: 2020, cnt: 0, dl: '2020-03-01', mv: [{dl: '2020-03-02', vl: 30}, ...] }]
68
+ # @return [Array<Hash>] lista dados contrato arrendamento (inclui lista movimentos novos)
69
+ def ctlct
70
+ @ctlct ||= []
71
+ end
72
+
73
+ # @return [String] texto formatado que representa lista de contratos arrendamento
74
+ def str_lc(sep = "'")
75
+ ctlct.map { |cid| sep + cid[:ct] + sep }.join(',')
76
+ end
77
+
78
+ # @return [String] sql para obter ultima renda do contrato arrendamento
79
+ def sql_last_re
80
+ 'select ct,DATE_SUB(DATE_SUB(dl,INTERVAL dias DAY),INTERVAL IF(cnt=0,0,cnt-1) MONTH) dc,ano,cnt,dl'\
81
+ ',CAST(REGEXP_EXTRACT(ct,r"\d+") as numeric)/100 vr '\
82
+ "from #{BD}.re where ct='#{opcao[:c]}' order by ano desc,cnt desc limit 1"
83
+ end
84
+
85
+ # @return [String] sql para obter movimentos novos (depois da ultima renda do contrato arrendamento)
86
+ def sql_novo_mv(mdl)
87
+ "select dl,vl from #{BD}.mv where ct='#{opcao[:c]}' and dl>='#{(mdl + 1).strftime(DF)}' order by dl,dv"
88
+ end
89
+
90
+ # @return [String] sql para obter dados do inicio contrato arrendamento
91
+ def sql_contrato_mv
92
+ cti = opcao[:c]
93
+ dat = opcao[:d]
94
+ if dat.empty?
95
+ 'select ct,EXTRACT(YEAR FROM DATE_TRUNC(dl,MONTH)) ano,0 cnt,DATE_TRUNC(dl,MONTH) dl,0 dias '\
96
+ "from #{BD}.mv where ct='#{cti}' order by dl limit 1"
97
+ else
98
+ "select '#{cti}' ct,EXTRACT(YEAR FROM DATE '#{dat}') ano,0 cnt,DATE '#{dat}' dl,0 dias"
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Abank
4
+ # @see Big
5
+ class Big
6
+ # @return [Integer] movimento do contrato arrendamento em tratamento
7
+ attr_reader :mvpos
8
+
9
+ # (see CLI#recriare)
10
+ def re_atualiza
11
+ # [re]cria rendas novas/todas dos contratos ativos
12
+ @ctlct = sql("select distinct ct from #{BD}.re")
13
+ re_apaga.ct_dados.re_insert
14
+ end
15
+
16
+ # insere rendas associadas a lista contratos arrendamento no bigquery
17
+ def re_insert
18
+ @ctpos = 0
19
+ vls = ct_rendas.join(',')
20
+ if vls.empty?
21
+ puts('NAO EXISTEM RENDAS NOVAS')
22
+ else
23
+ dml("insert #{BD}.re VALUES#{vls}")
24
+ puts("RENDAS #{str_lc('')} CRIADAS #{bqnrs}")
25
+ end
26
+ end
27
+
28
+ # apaga rendas da lista de contrato arrendamento
29
+ #
30
+ # @return [Big] acesso a base dados abank no bigquery
31
+ def re_apaga
32
+ return self if !opcao[:t] || ctlct.empty?
33
+
34
+ # para nao apagar contrato arrendamento - somente as rendas
35
+ opcao[:t] = false
36
+
37
+ re_delete_dml
38
+ self
39
+ end
40
+
41
+ # @return [Array<String>] lista rendas novas dum contrato arrendamento
42
+ def re_rendas
43
+ lre = []
44
+ while mvpos < re_atual[:mv].size && re_saldo_mv?
45
+ lre << re_nova_renda
46
+ @mvpos += 1 unless re_saldo_mv?
47
+ end
48
+ lre
49
+ end
50
+
51
+ # @return [String] renda formatada (values.re)
52
+ def re_nova_renda
53
+ re_proximos_dados
54
+ "('#{re_atual[:ct]}',#{ano},#{cnt},'#{re_atual_mv[:dl].strftime(DF)}',#{dias})"
55
+ end
56
+
57
+ # @return [Hash] dados contrato arrendamento (inclui lista movimentos novos)
58
+ def re_proximos_dados
59
+ # valor renda paga retirada do movimento
60
+ re_atual_mv[:vl] -= re_atual[:vr]
61
+ dre = cnt.zero? ? Date.new(ano, 1, 1) : Date.new(ano, cnt, 1) >> 1
62
+ re_atual.merge!(ano: dre.year, cnt: dre.month)
63
+ end
64
+
65
+ # apaga rendas da lista de contratos arrendamento
66
+ def re_delete_dml
67
+ dml("delete from #{BD}.re where ct in(#{str_lc})#{opcao[:t] ? '' : ' and cnt>0'}")
68
+ puts("RENDAS #{str_lc('')} APAGADAS #{bqnrs}")
69
+ end
70
+
71
+ # @return [Boolean] movimento com saldo suficiente?
72
+ def re_saldo_mv?
73
+ re_atual_mv[:vl] >= re_atual[:vr]
74
+ end
75
+
76
+ # @return [Hash] dados contrato arrendamento atual (inclui lista movimentos novos)
77
+ def re_atual
78
+ ctlct[ctpos]
79
+ end
80
+
81
+ # @return [Hash] movimento atual contrato arrendamento
82
+ def re_atual_mv
83
+ re_atual[:mv][mvpos]
84
+ end
85
+
86
+ # @return [Integer] ano da renda
87
+ def ano
88
+ re_atual[:ano]
89
+ end
90
+
91
+ # @return [Integer] numero da renda (0-12)
92
+ def cnt
93
+ re_atual[:cnt]
94
+ end
95
+
96
+ # @return [Integer] dias atraso/antecipo neste pagamento renda
97
+ def dias
98
+ re_atual_mv[:dl].mjd - (Date.new(ano, cnt, 1) >> (re_atual[:dc].month - 1)).mjd
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('roo')
4
+
5
+ module Abank
6
+ # @see Folha
7
+ class Folha < Big
8
+ # @return [Roo::Excelx] folha calculo a processar
9
+ # attr_reader :folha
10
+
11
+ # @return [Array] row folha calculo em processamento
12
+ attr_reader :rowfc
13
+
14
+ # @return [String] movimentos a inserir (values.mv)
15
+ attr_reader :mvvls
16
+
17
+ # acesso a folha calculo & base dados abank no bigquery
18
+ #
19
+ # @param [String] xls folha calculo a processar
20
+ # @param [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho
21
+ # @option opcoes [Boolean] :s (false) apaga movimento similar? (mv)
22
+ # @option opcoes [Boolean] :e (false) apaga movimento igual? (mv)
23
+ # @option opcoes [Boolean] :i (false) insere movimento novo? (mv)
24
+ # @option opcoes [String] :v ('') data valor movimentos (mv)
25
+ # @option opcoes [String] :g ('') classificacao movimentos (mv)
26
+ def initialize(opcoes = {})
27
+ @opcao = super
28
+ @opcao[:s] = opcoes.fetch(:s, false)
29
+ @opcao[:e] = opcoes.fetch(:e, false)
30
+ @opcao[:i] = opcoes.fetch(:i, false)
31
+ @opcao[:v] = opcoes.fetch(:v, '')
32
+ @opcao[:g] = opcoes.fetch(:g, '')
33
+ # acumuladores necessitam init
34
+ @opcao[:k] = ''
35
+ @mvvls = ''
36
+ end
37
+
38
+ # @return [Roo::Excelx] folha calculo a processar
39
+ def folha
40
+ @folha ||= Roo::Spreadsheet.open(opcao[:f])
41
+ end
42
+
43
+ # carrega/mostra folha calculo
44
+ def processa_xls
45
+ puts("\n#{folha.info}")
46
+ folha.sheet(0).parse(header_search: ['Data Lanc.', 'Data Valor', 'Descrição', 'Valor']) do |row|
47
+ puts(processa_linha) if ok?(row)
48
+ end
49
+ return unless opcao[:i]
50
+
51
+ # processa movimentos & atualiza rendas
52
+ mv_delete.mv_insert.ct_dados.re_insert
53
+ end
54
+
55
+ # @return [Integer] numero conta associado a folha calculo
56
+ # @example
57
+ # mov*.xlsx --> 1 --> conta-corrente
58
+ # movCard*.xlsx --> 2 --> conta-cartao
59
+ def conta
60
+ opcao[:f].match?(/card/i) ? 2 : 1
61
+ end
62
+
63
+ # @param [Hash] linha da folha calculo em processamento
64
+ # @return [Boolean] linha com valores para processar?
65
+ def ok?(linha)
66
+ @rowfc = linha.values
67
+ return false if rowfc[0].is_a?(String)
68
+
69
+ rowfc[2] = rowfc[2].strip
70
+ rowfc[3] = -1 * rowfc[3] if conta > 1
71
+ true
72
+ end
73
+
74
+ # @return [String] texto informativo formatado da linha processada
75
+ def processa_linha
76
+ # pesquisa existencia linha folha calculo no bigquery
77
+ # array.count = 0 ==> pode carregar esta linha
78
+ # array.count = 1 ==> mais testes necessarios
79
+ # array.count > 1 ==> nao pode carregar esta linha
80
+ sql(sql_existe_mv, [{}, {}])
81
+
82
+ if linha_naoexiste? then linha_base + values_mv
83
+ elsif linha_existe? then linha_existe
84
+ elsif linha_simila? then linha_similar
85
+ else linha_multiplas
86
+ end
87
+ end
88
+
89
+ # insere & classifica movimentos no bigquery
90
+ #
91
+ # @return [Big] acesso a base dados abank no bigquery
92
+ def mv_insert
93
+ unless mvvls.empty?
94
+ @mvvls = mvvls[1..] if mvvls[0] == ','
95
+ dml("insert #{BD}.mv VALUES#{mvvls}")
96
+ puts("MOVIMENTOS INSERIDOS #{bqnrs}")
97
+ mv_classifica if bqnrs.positive?
98
+ end
99
+ self
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Abank
4
+ # acesso a folha calculo & base dados abank no bigquery
5
+ class Folha < Big
6
+ # @return [Boolean] linha folha calculo nao existe no bigquery?
7
+ def linha_naoexiste?
8
+ bqres.empty?
9
+ end
10
+
11
+ # @return [Boolean] linha folha calculo existe no bigquery?
12
+ def linha_existe?
13
+ bqres.count == 1 && bqres.first[:ds].strip == rowfc[2]
14
+ end
15
+
16
+ # @return [Boolean] linha folha calculo existe parecida no bigquery?
17
+ def linha_simila?
18
+ bqres.count == 1 && bqres.first[:ds].strip != rowfc[2]
19
+ end
20
+
21
+ # @return [String] texto base formatado para display
22
+ def linha_base
23
+ "#{rowfc[0].strftime(DF)} #{format('%<v3>-34.34s %<v4>8.2f', v3: rowfc[2], v4: rowfc[3])}"
24
+ end
25
+
26
+ # @return [String] texto linha existente formatada para display
27
+ def linha_existe
28
+ add_kys if opcao[:e]
29
+ "#{linha_base} EXIS #{format('%<v1>20d', v1: bqres.first[:ky])}"
30
+ end
31
+
32
+ # @return [String] texto linha similar formatada para display
33
+ def linha_similar
34
+ add_kys if opcao[:s]
35
+ "#{linha_base} SIMI #{format('%<v1>-20.20s', v1: bqres.first[:ds].strip)}"
36
+ end
37
+
38
+ # @return [String] texto linha existencia multipla formatada para display
39
+ def linha_multiplas
40
+ "#{linha_base} MULT(#{bqres.count})"
41
+ end
42
+
43
+ # obtem chaves movimento (keysin.mv) para apagar
44
+ def add_kys
45
+ bqres.each { |row| opcao[:k] += ",#{row[:ky]}" }
46
+ end
47
+
48
+ # @return [String] sql para movimentos no bigquery
49
+ def sql_existe_mv
50
+ "select *,#{ky_mv} as ky from #{BD}.mv where nc=#{conta} and dl='#{rowfc[0].strftime(DF)}' and vl=#{rowfc[3]}"
51
+ end
52
+
53
+ # obtem movimento (values.mv) para inserir
54
+ #
55
+ # @return [String] ' NOVO'
56
+ def values_mv
57
+ @mvvls += ",('#{rowfc[0].strftime(DF)}','#{dvc.strftime(DF)}','#{rowfc[2]}',#{rowfc[3]}"\
58
+ ",#{conta},#{dvc.year},#{dvc.month},'#{tpc}',#{ctc})"
59
+ ' NOVO'
60
+ end
61
+
62
+ # @return [Date] data valor corrigida
63
+ def dvc
64
+ dvl = opcao[:v]
65
+ dvl.empty? ? rowfc[1] : Date.parse(dvl)
66
+ end
67
+
68
+ # @return [String] classificacao do movimento (null --> classificacao automatica)
69
+ def ctc
70
+ cmv = opcao[:g]
71
+ cmv.empty? ? 'null' : "'#{cmv}'"
72
+ end
73
+
74
+ # @return [String] tipo movimento c[redito] ou d[ebito]
75
+ def tpc
76
+ rowfc[3].positive? ? 'c' : 'd'
77
+ end
78
+ end
79
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Abank
4
- VERSION = '0.2.5'
4
+ VERSION = '0.3.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abank
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hernâni Rodrigues Vaz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2020-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,13 +39,13 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: google-cloud-bigquery
42
+ name: reek
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
- type: :runtime
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
@@ -53,7 +53,49 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: roo
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: solargraph
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: google-cloud-bigquery
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
101
  - - ">="
@@ -67,7 +109,7 @@ dependencies:
67
109
  - !ruby/object:Gem::Version
68
110
  version: '0'
69
111
  - !ruby/object:Gem::Dependency
70
- name: thor
112
+ name: roo
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
115
  - - ">="
@@ -81,7 +123,7 @@ dependencies:
81
123
  - !ruby/object:Gem::Version
82
124
  version: '0'
83
125
  - !ruby/object:Gem::Dependency
84
- name: yard
126
+ name: thor
85
127
  requirement: !ruby/object:Gem::Requirement
86
128
  requirements:
87
129
  - - ">="
@@ -117,10 +159,11 @@ files:
117
159
  - bin/setup
118
160
  - exe/abank
119
161
  - lib/abank.rb
120
- - lib/abank/big.rb
121
- - lib/abank/contrato.rb
122
- - lib/abank/folha.rb
123
- - lib/abank/rendas.rb
162
+ - lib/abank/big1.rb
163
+ - lib/abank/big2.rb
164
+ - lib/abank/big3.rb
165
+ - lib/abank/folha1.rb
166
+ - lib/abank/folha2.rb
124
167
  - lib/abank/version.rb
125
168
  homepage: https://github.com/hernanirvaz/abank
126
169
  licenses:
@@ -134,16 +177,16 @@ require_paths:
134
177
  - lib
135
178
  required_ruby_version: !ruby/object:Gem::Requirement
136
179
  requirements:
137
- - - ">="
180
+ - - "~>"
138
181
  - !ruby/object:Gem::Version
139
- version: 2.3.0
182
+ version: '2.7'
140
183
  required_rubygems_version: !ruby/object:Gem::Requirement
141
184
  requirements:
142
185
  - - ">="
143
186
  - !ruby/object:Gem::Version
144
187
  version: '0'
145
188
  requirements: []
146
- rubygems_version: 3.0.8
189
+ rubygems_version: 3.1.2
147
190
  signing_key:
148
191
  specification_version: 4
149
192
  summary: Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery.