abank 0.2.10 → 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,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.10'
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.10
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-09-21 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,9 +177,9 @@ 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
  - - ">="
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require('google/cloud/bigquery')
4
-
5
- module Abank
6
- # @see Big
7
- class Big
8
- DF = '%Y-%m-%d'
9
-
10
- # @return [Hash] opcoes trabalho
11
- attr_reader :opcao
12
-
13
- # @return [Google::Cloud::Bigquery] API bigquery
14
- attr_reader :bqapi
15
-
16
- # @return [Google::Cloud::Bigquery::QueryJob] job bigquery
17
- attr_reader :bqjob
18
-
19
- # @return [Google::Cloud::Bigquery::Data] resultado do select
20
- attr_reader :bqres
21
-
22
- # @return [Integer] numero linhas afetadas pela Data Manipulation Language (DML)
23
- attr_reader :bqnrs
24
-
25
- # @return [String] movimentos a inserir (values.mv)
26
- attr_reader :mvvls
27
-
28
- # @return [String] movimentos a apagar (keysin.mv)
29
- attr_reader :mvkys
30
-
31
- # acesso a base dados abank no bigquery
32
- #
33
- # @param [Hash] opc opcoes trabalho
34
- # @option opc [String] :k ('') movimentos a apagar (keysin.mv)
35
- # @option opc [String] :c ('') id contrato arrendamento (re)
36
- # @option opc [String] :d ('') data inicio contrato arrendamento (re)
37
- # @option opc [Boolean] :t (false) trabalha todas as rendas? (re)
38
- # @return [Hash] opcoes trabalho
39
- def initialize(opc = {})
40
- @opcao = opc
41
- @bqapi = Google::Cloud::Bigquery.new
42
- @mvvls = ''
43
- @mvkys = opc.fetch(:k, '')
44
- @ctide = opc.fetch(:c, '')
45
- opcao
46
- end
47
-
48
- # (see CLI#tag)
49
- def mv_classifica
50
- dml("update #{BD}.mv set mv.ct=tt.nct from (select * from #{BD}.cl) as tt where #{ky_mv}=tt.ky")
51
- puts("MOVIMENTOS CLASSIFICADOS #{bqnrs}")
52
- end
53
-
54
- # apaga movimentos & suas rendas associadas no bigquery
55
- #
56
- # @return [Big] acesso a base dados abank no bigquery
57
- def mv_delete
58
- vars_mv_work
59
- if mvkys.size.positive?
60
- # obtem lista contratos arrendamento associados aos movimentos a apagar
61
- @ctlct = sql("select ct from #{BD}.mv where #{ky_mv} in(#{mvkys}) and substr(ct,1,1)='r' group by 1")
62
-
63
- # apaga rendas associadas e depois movimentos
64
- @opcao[:t] = true
65
- lr_apaga.mv_delete_dml
66
-
67
- # para obrigar re_work a trabalhar com lista contratos (ctlct)
68
- @bqnrs = 0
69
- else
70
- end
71
- self
72
- end
73
-
74
- # insere & classifica movimentos no bigquery
75
- #
76
- # @return [Big] acesso a base dados abank no bigquery
77
- def mv_insert
78
- if mvvls.size.positive?
79
- dml("insert #{BD}.mv VALUES#{mvvls}")
80
- puts("MOVIMENTOS INSERIDOS #{bqnrs}")
81
- mv_classifica if bqnrs.positive?
82
- else
83
- end
84
- self
85
- end
86
-
87
- # inicializa variaveis para delete/insert movimentos
88
- def vars_mv_work
89
- @bqnrs = 0
90
- @ctlct = []
91
- @mvkys = mvkys[1..] if mvkys[0] == ','
92
- @mvvls = mvvls[1..] if mvvls[0] == ','
93
- end
94
-
95
- # apaga movimentos no bigquery
96
- def mv_delete_dml
97
- dml("delete from #{BD}.mv where #{ky_mv} in(#{mvkys})")
98
- puts("MOVIMENTOS APAGADOS #{bqnrs}")
99
- end
100
-
101
- # @return [String] expressao sql da chave de movimentos
102
- def ky_mv
103
- 'FARM_FINGERPRINT(CONCAT(CAST(mv.nc as STRING),mv.ds,CAST(mv.dl as STRING),CAST(mv.vl as STRING)))'
104
- end
105
-
106
- # cria job bigquery & verifica execucao
107
- #
108
- # @param [String] cmd comando a executar
109
- # @return [Boolean] job ok?
110
- def job?(cmd)
111
- # p cmd
112
- @bqjob = bqapi.query_job(cmd)
113
- @bqjob.wait_until_done!
114
- puts(@bqjob.error['message']) if @bqjob.failed?
115
- @bqjob.failed?
116
- end
117
-
118
- # executa sql & devolve resultado do bigquery
119
- #
120
- # @param (see job?)
121
- # @param [Array] erro quando da erro no bigquery
122
- # @return [Google::Cloud::Bigquery::Data] resultado do sql
123
- def sql(cmd, erro = [])
124
- @bqres = job?(cmd) ? erro : bqjob.data
125
- end
126
-
127
- # executa Data Manipulation Language (DML) no bigquery
128
- #
129
- # @param (see job?)
130
- # @return [Integer] numero rows afetadas pelo dml
131
- def dml(cmd)
132
- @bqnrs = job?(cmd) ? 0 : bqjob.num_dml_affected_rows
133
- end
134
- end
135
- end