abank 0.2.0 → 0.2.5
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 +4 -4
- data/.rubocop.yml +33 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +7 -7
- data/README.md +9 -5
- data/Rakefile +4 -2
- data/abank.gemspec +7 -10
- data/bin/console +4 -3
- data/lib/abank.rb +70 -31
- data/lib/abank/big.rb +134 -0
- data/lib/abank/contrato.rb +107 -0
- data/lib/abank/folha.rb +154 -0
- data/lib/abank/rendas.rb +121 -0
- data/lib/abank/version.rb +1 -1
- metadata +12 -9
- data/lib/abank/bigquery.rb +0 -115
- data/lib/abank/folhacalculo.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 357eabd6927351fcd006bf58dda24c7b323395749b4ab6ef4ecf6f596a126241
|
4
|
+
data.tar.gz: 0c3fc3b9e2ebda8bfe13b0ba072f50b0ff303668dfde4ffa7378e04f1470b81e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b11a19c0f7039ff253776441e4f7b7de443808c4bf90dfec078a65dab3342b40197017d36e69d30d09d35500afd6e187ebe7113580e36ef921737085599c26af
|
7
|
+
data.tar.gz: 98daf017bef2b5860fe498c9f11f6881374ebaa87451a10bf24fe1fa95006230c734a6dc1176e036983ec0e991777e59cfebaa34f2c2bc67828d3b95563163ae
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.6
|
3
|
+
EnabledByDefault: true
|
4
|
+
|
5
|
+
Style/ClassAndModuleChildren:
|
6
|
+
EnforcedStyle: compact
|
7
|
+
|
8
|
+
Style/Copyright:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/DocumentationMethod:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/MethodCallWithArgsParentheses:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Style/ConstantVisibility:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Layout/MultilineMethodArgumentLineBreaks:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Layout/MultilineHashKeyLineBreaks:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Layout/FirstMethodParameterLineBreak:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Layout/FirstHashElementLineBreak:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/MissingElse:
|
33
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
abank (0.2.
|
4
|
+
abank (0.2.5)
|
5
5
|
google-cloud-bigquery
|
6
6
|
roo
|
7
7
|
thor
|
@@ -17,7 +17,7 @@ GEM
|
|
17
17
|
declarative-option (0.1.0)
|
18
18
|
faraday (1.0.1)
|
19
19
|
multipart-post (>= 1.2, < 3)
|
20
|
-
google-api-client (0.
|
20
|
+
google-api-client (0.40.1)
|
21
21
|
addressable (~> 2.5, >= 2.5.1)
|
22
22
|
googleauth (~> 0.9)
|
23
23
|
httpclient (>= 2.8.1, < 3.0)
|
@@ -25,7 +25,7 @@ GEM
|
|
25
25
|
representable (~> 3.0)
|
26
26
|
retriable (>= 2.0, < 4.0)
|
27
27
|
signet (~> 0.12)
|
28
|
-
google-cloud-bigquery (1.21.
|
28
|
+
google-cloud-bigquery (1.21.1)
|
29
29
|
concurrent-ruby (~> 1.0)
|
30
30
|
google-api-client (~> 0.33)
|
31
31
|
google-cloud-core (~> 1.2)
|
@@ -34,9 +34,9 @@ GEM
|
|
34
34
|
google-cloud-core (1.5.0)
|
35
35
|
google-cloud-env (~> 1.0)
|
36
36
|
google-cloud-errors (~> 1.0)
|
37
|
-
google-cloud-env (1.3.
|
37
|
+
google-cloud-env (1.3.2)
|
38
38
|
faraday (>= 0.17.3, < 2.0)
|
39
|
-
google-cloud-errors (1.0.
|
39
|
+
google-cloud-errors (1.0.1)
|
40
40
|
googleauth (0.12.0)
|
41
41
|
faraday (>= 0.17.3, < 2.0)
|
42
42
|
jwt (>= 1.4, < 3.0)
|
@@ -54,7 +54,7 @@ GEM
|
|
54
54
|
nokogiri (1.10.9)
|
55
55
|
mini_portile2 (~> 2.4.0)
|
56
56
|
os (1.1.0)
|
57
|
-
public_suffix (4.0.
|
57
|
+
public_suffix (4.0.5)
|
58
58
|
rake (12.3.3)
|
59
59
|
representable (3.0.4)
|
60
60
|
declarative (< 0.1.0)
|
@@ -72,7 +72,7 @@ GEM
|
|
72
72
|
multi_json (~> 1.10)
|
73
73
|
thor (1.0.1)
|
74
74
|
uber (0.1.0)
|
75
|
-
yard (0.9.
|
75
|
+
yard (0.9.25)
|
76
76
|
|
77
77
|
PLATFORMS
|
78
78
|
ruby
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Abank [](https://travis-ci.com/hernanirvaz/abank)
|
2
2
|
|
3
|
-
Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery. Permite apagar movimentos
|
3
|
+
Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery. Permite apagar/recriar movimentos/rendas ja no bigquery. Permite ainda classificar movimentos no bigquery.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -20,10 +20,14 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
$ abank
|
24
|
-
$ abank
|
25
|
-
$ abank
|
26
|
-
$ abank
|
23
|
+
$ abank apagamv -k=KEY[,KEY...] # apaga movimentos
|
24
|
+
$ abank apagact -c=CONTRATO # apaga contrato arrendamento
|
25
|
+
$ abank criact -c=CONTRATO # cria contrato arrendamento
|
26
|
+
$ abank recriact -c=CONTRATO # atualiza rendas de contrato arrendamento
|
27
|
+
$ abank recriare # atualiza rendas dos contratos ativos
|
28
|
+
$ abank load # carrega dados da folha calculo
|
29
|
+
$ abank show # mostra dados da folha calculo
|
30
|
+
$ abank tag # classifica movimentos
|
27
31
|
|
28
32
|
## Development
|
29
33
|
|
data/Rakefile
CHANGED
data/abank.gemspec
CHANGED
@@ -10,12 +10,9 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.homepage = 'https://github.com/hernanirvaz/abank'
|
11
11
|
spec.license = 'MIT'
|
12
12
|
|
13
|
-
spec.summary = 'Arquiva
|
14
|
-
|
15
|
-
|
16
|
-
' Pode apagar movimentos similares/existentes' \
|
17
|
-
' ja no bigquery.' \
|
18
|
-
' Pode ainda classificar movimentos ja no bigquery.'
|
13
|
+
spec.summary = 'Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery.'
|
14
|
+
spec.description = spec.summary + ' Permite apagar/recriar movimentos/rendas ja no bigquery. ' \
|
15
|
+
' Permite ainda classificar movimentos no bigquery.'
|
19
16
|
|
20
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
21
18
|
spec.metadata['yard.run'] = 'yard'
|
@@ -24,10 +21,10 @@ Gem::Specification.new do |spec|
|
|
24
21
|
|
25
22
|
# Specify which files should be added to the gem when it is released.
|
26
23
|
# The `git ls-files -z` loads files in RubyGem that have been added into git.
|
27
|
-
spec.files =
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
spec.files =
|
25
|
+
Dir.chdir(File.expand_path(__dir__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
|
+
end
|
31
28
|
spec.bindir = 'exe'
|
32
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
30
|
spec.require_paths = ['lib']
|
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'abank'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require "abank"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require 'irb'
|
14
15
|
IRB.start(__FILE__)
|
data/lib/abank.rb
CHANGED
@@ -1,55 +1,94 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'thor'
|
4
|
-
require 'abank/
|
5
|
-
require 'abank/
|
4
|
+
require 'abank/big'
|
5
|
+
require 'abank/contrato'
|
6
|
+
require 'abank/folha'
|
7
|
+
require 'abank/rendas'
|
6
8
|
require 'abank/version'
|
7
9
|
|
8
10
|
# @author Hernani Rodrigues Vaz
|
9
11
|
module Abank
|
10
|
-
|
12
|
+
DR = "/home/#{`whoami`.chomp}/Downloads"
|
11
13
|
|
12
14
|
class Error < StandardError; end
|
13
15
|
|
14
16
|
# CLI para carregar folhas calculo comuns no bigquery
|
15
17
|
class CLI < Thor
|
16
|
-
desc '
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
option :
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
desc 'tag', 'classifica movimentos'
|
19
|
+
# classifica movimentos
|
20
|
+
def tag
|
21
|
+
Big.new.mv_classifica
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'apagamv', 'apaga movimentos'
|
25
|
+
option :k, banner: 'KEY[,KEY...]', required: true, desc: 'keys movimentos a apagar'
|
26
|
+
# apaga movimentos
|
27
|
+
def apagamv
|
28
|
+
Big.new(k: options[:k]).mv_delete.mv_insert.re_work
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'criact', 'cria contrato arrendamento'
|
32
|
+
option :c, banner: 'CONTRATO', required: true, desc: 'Identificador contrato arrendamento'
|
33
|
+
option :t, type: :boolean, default: true, desc: 'cria todas as rendas?'
|
34
|
+
option :d, banner: 'DATA', default: '', desc: 'data contrato arrendamento'
|
35
|
+
# cria contrato arrendamento
|
36
|
+
def criact
|
37
|
+
Big.new(c: options[:c], t: options[:t], d: options[:d]).ct_cria
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'apagact', 'apaga contrato arrendamento'
|
41
|
+
option :c, banner: 'CONTRATO', required: true, desc: 'Identificador contrato arrendamento'
|
42
|
+
option :t, type: :boolean, default: false, desc: 'apaga todas as rendas?'
|
43
|
+
# apaga contrato arrendamento
|
44
|
+
def apagact
|
45
|
+
Big.new(c: options[:c], t: options[:t]).ct_apaga
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'recriact', 'atualiza rendas de contrato arrendamento'
|
49
|
+
option :c, banner: 'CONTRATO', required: true, desc: 'Identificador contrato arrendamento'
|
50
|
+
option :t, type: :boolean, default: false, desc: 'apaga todas as rendas?'
|
51
|
+
option :d, banner: 'DATA', default: '', desc: 'data contrato arrendamento'
|
52
|
+
# atualiza rendas de contrato arrendamento
|
53
|
+
def recriact
|
54
|
+
Big.new(c: options[:c], t: options[:t]).ct_apaga
|
55
|
+
Big.new(c: options[:c], t: true, d: options[:d]).ct_cria
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'recriare', 'atualiza rendas dos contratos ativos'
|
59
|
+
option :t, type: :boolean, default: false, desc: 'atualiza todas as rendas?'
|
60
|
+
# atualiza rendas dos contratos ativos
|
61
|
+
def recriare
|
62
|
+
Big.new(t: options[:t]).re_atualiza
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'load', 'carrega dados da folha calculo'
|
66
|
+
option :s, type: :boolean, default: false, desc: 'apaga movimento similar'
|
67
|
+
option :e, type: :boolean, default: false, desc: 'apaga movimento igual'
|
68
|
+
option :v, banner: 'DATA', default: '', desc: 'data valor para movimentos a carregar'
|
69
|
+
option :g, banner: 'TAG', default: '', desc: 'classificacao para movimentos a carregar'
|
70
|
+
# carrega folha calculo
|
28
71
|
def load
|
29
|
-
Dir.glob("#{
|
30
|
-
|
31
|
-
m: options[:m], i: true }).processa
|
72
|
+
Dir.glob("#{DR}/*.xlsx").sort.each do |f|
|
73
|
+
Big::Folha.new(load_opc.merge(f: f)).processa_xls
|
32
74
|
end
|
33
75
|
end
|
34
76
|
|
35
|
-
desc '
|
36
|
-
option :d, banner: 'DIR', default: "/home/#{ID}/Downloads",
|
37
|
-
desc: 'Onde procurar folhas calculo'
|
38
|
-
option :x, banner: 'EXT', default: '.xlsx',
|
39
|
-
desc: 'Extensao das folhas calculo'
|
77
|
+
desc 'show', 'mostra dados da folha calculo'
|
40
78
|
# mostra folha calculo
|
41
|
-
def
|
42
|
-
Dir.glob("#{
|
43
|
-
|
79
|
+
def show
|
80
|
+
Dir.glob("#{DR}/*.xlsx").sort.each do |f|
|
81
|
+
Big::Folha.new(f: f).processa_xls
|
44
82
|
end
|
45
83
|
end
|
46
84
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
85
|
+
no_commands do
|
86
|
+
# @return [Hash] opcoes trabalho com movimentos para load
|
87
|
+
def load_opc
|
88
|
+
{ s: options[:s], e: options[:e], i: true, v: options[:v], g: options[:g] }
|
89
|
+
end
|
51
90
|
end
|
52
91
|
|
53
|
-
default_task :
|
92
|
+
default_task :show
|
54
93
|
end
|
55
94
|
end
|
data/lib/abank/big.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'google/cloud/bigquery'
|
4
|
+
|
5
|
+
# @see Abank::Big
|
6
|
+
class Abank::Big
|
7
|
+
DF = '%Y-%m-%d'
|
8
|
+
|
9
|
+
# @return [Hash] opcoes trabalho
|
10
|
+
attr_reader :opcao
|
11
|
+
|
12
|
+
# @return [Google::Cloud::Bigquery] API bigquery
|
13
|
+
attr_reader :bqapi
|
14
|
+
|
15
|
+
# @return [Google::Cloud::Bigquery::QueryJob] job bigquery
|
16
|
+
attr_reader :bqjob
|
17
|
+
|
18
|
+
# @return [Google::Cloud::Bigquery::Data] resultado do select
|
19
|
+
attr_reader :bqres
|
20
|
+
|
21
|
+
# @return [Integer] numero linhas afetadas pela Data Manipulation Language (DML)
|
22
|
+
attr_reader :bqnrs
|
23
|
+
|
24
|
+
# @return [String] movimentos a inserir (values.mv)
|
25
|
+
attr_reader :mvvls
|
26
|
+
|
27
|
+
# @return [String] movimentos a apagar (keysin.mv)
|
28
|
+
attr_reader :mvkys
|
29
|
+
|
30
|
+
# acesso a base dados abank no bigquery
|
31
|
+
#
|
32
|
+
# @param [Hash] opc opcoes trabalho
|
33
|
+
# @option opc [String] :k ('') movimentos a apagar (keysin.mv)
|
34
|
+
# @option opc [String] :c ('') id contrato arrendamento (re)
|
35
|
+
# @option opc [String] :d ('') data inicio contrato arrendamento (re)
|
36
|
+
# @option opc [Boolean] :t (false) trabalha todas as rendas? (re)
|
37
|
+
# @return [Hash] opcoes trabalho
|
38
|
+
def initialize(opc = {})
|
39
|
+
@opcao = opc
|
40
|
+
@bqapi = Google::Cloud::Bigquery.new
|
41
|
+
@mvvls = ''
|
42
|
+
@mvkys = opc.fetch(:k, '')
|
43
|
+
@ctide = opc.fetch(:c, '')
|
44
|
+
# p ['B', opcao]
|
45
|
+
opcao
|
46
|
+
end
|
47
|
+
|
48
|
+
# (see CLI#tag)
|
49
|
+
def mv_classifica
|
50
|
+
dml('update hernanilr.ab.mv set mv.ct=tt.nct ' \
|
51
|
+
'from (select * from hernanilr.ab.cl) as tt ' \
|
52
|
+
"where #{ky_mv}=tt.ky")
|
53
|
+
puts 'MOVIMENTOS CLASSIFICADOS ' + bqnrs.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
# apaga movimentos & suas rendas associadas no bigquery
|
57
|
+
#
|
58
|
+
# @return [Big] acesso a base dados abank no bigquery
|
59
|
+
def mv_delete
|
60
|
+
vars_mv_work
|
61
|
+
if mvkys.size.positive?
|
62
|
+
# obtem lista contratos arrendamento associados aos movimentos a apagar
|
63
|
+
@ctlct = sel("select ct from hernanilr.ab.mv where #{ky_mv} in(#{mvkys}) and substr(ct,1,1)='r' group by 1")
|
64
|
+
|
65
|
+
# apaga rendas associadas e depois movimentos
|
66
|
+
@opcao[:t] = true
|
67
|
+
lr_apaga.mv_delete_dml
|
68
|
+
|
69
|
+
# para obrigar re_work a trabalhar com lista contratos (ctlct)
|
70
|
+
@bqnrs = 0
|
71
|
+
end
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# insere & classifica movimentos no bigquery
|
76
|
+
#
|
77
|
+
# @return [Big] acesso a base dados abank no bigquery
|
78
|
+
def mv_insert
|
79
|
+
if mvvls.size.positive?
|
80
|
+
dml('insert hernanilr.ab.mv VALUES' + mvvls)
|
81
|
+
puts 'MOVIMENTOS INSERIDOS ' + bqnrs.to_s
|
82
|
+
mv_classifica if bqnrs.positive?
|
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 hernanilr.ab.mv where #{ky_mv} in(#{mvkys})")
|
98
|
+
puts 'MOVIMENTOS APAGADOS ' + bqnrs.to_s
|
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] sql comando a executar
|
109
|
+
# @return [Boolean] job ok?
|
110
|
+
def job?(sql)
|
111
|
+
# p sql
|
112
|
+
@bqjob = bqapi.query_job(sql)
|
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 sel(sql, erro = [])
|
124
|
+
@bqres = job?(sql) ? 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(sql)
|
132
|
+
@bqnrs = job?(sql) ? 0 : bqjob.num_dml_affected_rows
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# acesso a base dados abank no bigquery
|
4
|
+
class Abank::Big
|
5
|
+
# @return [String] id contrato arrendamento
|
6
|
+
attr_reader :ctide
|
7
|
+
|
8
|
+
# @return [Array<Hash>] lista ids contratos arrendamento
|
9
|
+
# @example
|
10
|
+
# [{ ct: 'r03000' }, ...]
|
11
|
+
attr_reader :ctlct
|
12
|
+
|
13
|
+
# @return [Array<Hash>] lista dados contrato arrendamento (inclui lista movimentos novos)
|
14
|
+
# @example
|
15
|
+
# [{ct: 'r03000', dc: '2020-03-01', ano: 2020, cnt: 0, dl: '2020-03-01', mv: [{dl: '2020-03-02', vl: 30}, ...] }]
|
16
|
+
attr_reader :ctlcm
|
17
|
+
|
18
|
+
# (see CLI#criact)
|
19
|
+
def ct_cria
|
20
|
+
if existe_contrato?
|
21
|
+
@bqnrs = 1
|
22
|
+
puts 'CONTRATO JA EXISTE'
|
23
|
+
else
|
24
|
+
dml('insert into hernanilr.ab.re ' + sql_contrato_mv)
|
25
|
+
puts "CONTRATO #{ctide} " + (bqnrs.zero? ? 'NAO EXISTE' : 'INSERIDO')
|
26
|
+
end
|
27
|
+
return unless existem_rendas?
|
28
|
+
|
29
|
+
# processa rendas associadas ao contrato arrendamento
|
30
|
+
cm_cria.vr_cria.re_insert
|
31
|
+
end
|
32
|
+
|
33
|
+
# (see CLI#apagact)
|
34
|
+
def ct_apaga
|
35
|
+
@ctlct = [{ ct: ctide }]
|
36
|
+
lc_apaga
|
37
|
+
end
|
38
|
+
|
39
|
+
# apaga rendas da lista de contrato arrendamento
|
40
|
+
#
|
41
|
+
# @return [Big] acesso a base dados abank no bigquery
|
42
|
+
def lr_apaga
|
43
|
+
return self unless opcao[:t] && ctlct.count.positive?
|
44
|
+
|
45
|
+
# para nao apagar contrato arrendamento - somente as rendas
|
46
|
+
@opcao[:t] = false
|
47
|
+
|
48
|
+
lc_apaga
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
# apaga rendas da lista de contratos arrendamento
|
53
|
+
def lc_apaga
|
54
|
+
dml("delete from hernanilr.ab.re where ct in(#{str_lc})#{opcao[:t] ? '' : ' and cnt>0'}")
|
55
|
+
puts "RENDAS #{str_lc('')} APAGADAS " + bqnrs.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String] texto formatado que representa lista de contratos arrendamento
|
59
|
+
def str_lc(sep = "'")
|
60
|
+
ctlct.map { |c| sep + c[:ct] + sep }.join(',')
|
61
|
+
end
|
62
|
+
|
63
|
+
# optem lista dados contrato arrendamento (inclui lista movimentos novos)
|
64
|
+
#
|
65
|
+
# @return [Big] acesso a base dados abank no bigquery
|
66
|
+
def cm_cria
|
67
|
+
@ctlcm = []
|
68
|
+
ctlct.each do |c|
|
69
|
+
@ctide = c[:ct]
|
70
|
+
sel(sql_last_re)
|
71
|
+
@ctlcm << bqres[0].merge({ mv: sel(sql_novo_mv(bqres[0][:dl])) })
|
72
|
+
end
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Boolean] existem rendas para processar sim/nao?
|
77
|
+
def existem_rendas?
|
78
|
+
@ctlct = [{ ct: ctide }]
|
79
|
+
bqnrs.positive? && opcao[:t]
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Boolean] contrato arrendamento ja existe sim/nao?
|
83
|
+
def existe_contrato?
|
84
|
+
sel("select ct from hernanilr.ab.re where ct='#{ctide}' and cnt=0").count.positive?
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [String] sql para obter ultima renda do contrato arrendamento
|
88
|
+
def sql_last_re
|
89
|
+
'select ct,DATE_SUB(DATE_SUB(dl,INTERVAL dias DAY),INTERVAL IF(cnt=0,0,cnt-1) MONTH) as dc,ano,cnt,dl ' \
|
90
|
+
"from hernanilr.ab.re where ct='#{ctide}' order by ano desc,cnt desc limit 1"
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [String] sql para obter movimentos novos (depois da ultima renda do contrato arrendamento)
|
94
|
+
def sql_novo_mv(mdl)
|
95
|
+
"select dl,vl from hernanilr.ab.mv where ct='#{ctide}' and dl>='#{(mdl + 1).strftime(DF)}' order by dl,dv"
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [String] sql para obter dados do inicio contrato arrendamento
|
99
|
+
def sql_contrato_mv
|
100
|
+
if opcao[:d].size.zero?
|
101
|
+
'select ct,EXTRACT(YEAR FROM DATE_TRUNC(dl,MONTH)) as ano,0 as cnt,DATE_TRUNC(dl,MONTH) as dl,0 dias ' \
|
102
|
+
"from hernanilr.ab.mv where ct='#{ctide}' order by dl limit 1"
|
103
|
+
else
|
104
|
+
"select '#{ctide}' as ct,EXTRACT(YEAR FROM DATE '#{opcao[:d]}') as ano,0 as cnt,DATE '#{opcao[:d]}' as dl,0 dias"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/abank/folha.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'roo'
|
4
|
+
|
5
|
+
# acesso a folha calculo & base dados abank no bigquery
|
6
|
+
class Abank::Big::Folha < Abank::Big
|
7
|
+
# @return [Roo::Excelx] folha calculo a processar
|
8
|
+
attr_reader :folha
|
9
|
+
|
10
|
+
# @return [Integer] numero conta associado a folha calculo
|
11
|
+
# @example
|
12
|
+
# mov*.xlsx --> 1 --> conta-corrente
|
13
|
+
# movCard*.xlsx --> 2 --> conta-cartao
|
14
|
+
attr_reader :conta
|
15
|
+
|
16
|
+
# @return [Array] row folha calculo em processamento
|
17
|
+
attr_reader :rowfc
|
18
|
+
|
19
|
+
# acesso a folha calculo & base dados abank no bigquery
|
20
|
+
#
|
21
|
+
# @param [Hash] opc opcoes trabalho
|
22
|
+
# @option opc [String] :f ('') folha calculo a processar
|
23
|
+
# @option opc [Boolean] :s (false) apaga movimento similar? (mv)
|
24
|
+
# @option opc [Boolean] :e (false) apaga movimento igual? (mv)
|
25
|
+
# @option opc [Boolean] :i (false) insere movimento novo? (mv)
|
26
|
+
# @option opc [String] :v ('') data valor movimentos (mv)
|
27
|
+
# @option opc [String] :g ('') classificacao movimentos (mv)
|
28
|
+
def initialize(opc = {})
|
29
|
+
@opcao = super
|
30
|
+
@folha = Roo::Spreadsheet.open(opc.fetch(:f))
|
31
|
+
@conta = opc.fetch(:f).match?(/card/i) ? 2 : 1
|
32
|
+
@opcao[:s] = opc.fetch(:s, false)
|
33
|
+
@opcao[:e] = opc.fetch(:e, false)
|
34
|
+
@opcao[:i] = opc.fetch(:i, false)
|
35
|
+
@opcao[:v] = opc.fetch(:v, '')
|
36
|
+
@opcao[:g] = opc.fetch(:g, '')
|
37
|
+
end
|
38
|
+
|
39
|
+
# carrega/mostra folha calculo
|
40
|
+
def processa_xls
|
41
|
+
n = 0
|
42
|
+
folha.sheet(0).parse(header_search: ['Data Lanc.', 'Data Valor', 'Descrição', 'Valor']) do |r|
|
43
|
+
n += 1
|
44
|
+
puts n == 1 ? "\n" + folha.info : processa_linha(r)
|
45
|
+
end
|
46
|
+
return unless opcao[:i]
|
47
|
+
|
48
|
+
# processa movimentos & atualiza rendas
|
49
|
+
mv_delete.mv_insert.re_work
|
50
|
+
end
|
51
|
+
|
52
|
+
# processa linha folha calculo
|
53
|
+
#
|
54
|
+
# @param [Hash] linha da folha calculo em processamento
|
55
|
+
# @return [String] texto informativo formatado da linha em processamento
|
56
|
+
def processa_linha(linha)
|
57
|
+
vars_xls(linha)
|
58
|
+
# pesquisa existencia linha folha calculo no bigquery
|
59
|
+
# array.count = 0 ==> pode carregar esta linha
|
60
|
+
# array.count = 1 ==> mais testes necessarios
|
61
|
+
# array.count > 1 ==> nao pode carregar esta linha
|
62
|
+
sel(sql_existe_mv, [{}, {}])
|
63
|
+
if linha_naoexiste? then linha_base + values_mv
|
64
|
+
elsif linha_existe? then linha_existe
|
65
|
+
elsif linha_simila? then linha_similar
|
66
|
+
else linha_multiplas
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# inicializa variavel para processar linha folha calculo
|
71
|
+
#
|
72
|
+
# @param (see processa_linha)
|
73
|
+
def vars_xls(linha)
|
74
|
+
@rowfc = linha.values
|
75
|
+
@rowfc[2] = rowfc[2].strip
|
76
|
+
@rowfc[3] = -1 * rowfc[3] if conta > 1
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [String] texto base formatado para display
|
80
|
+
def linha_base
|
81
|
+
"#{rowfc[0].strftime(DF)} #{format('%<v3>-34.34s %<v4>8.2f', v3: rowfc[2], v4: rowfc[3])}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [String] texto linha existente formatada para display
|
85
|
+
def linha_existe
|
86
|
+
add_kys if opcao[:e]
|
87
|
+
linha_base + ' EXIS ' + format('%<v1>20d', v1: bqres.first[:ky])
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [String] texto linha similar formatada para display
|
91
|
+
def linha_similar
|
92
|
+
add_kys if opcao[:s]
|
93
|
+
linha_base + ' SIMI ' + format('%<v1>-20.20s', v1: bqres.first[:ds].strip)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [String] texto linha existencia multipla formatada para display
|
97
|
+
def linha_multiplas
|
98
|
+
linha_base + ' MULT(' + bqres.count.to_s + ')'
|
99
|
+
end
|
100
|
+
|
101
|
+
# obtem chaves movimento (keysin.mv) para apagar
|
102
|
+
def add_kys
|
103
|
+
bqres.each { |r| @mvkys += ",#{r[:ky]}" }
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Boolean] linha folha calculo nao existe no bigquery?
|
107
|
+
def linha_naoexiste?
|
108
|
+
bqres.count.zero?
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [Boolean] linha folha calculo existe no bigquery?
|
112
|
+
def linha_existe?
|
113
|
+
bqres.count == 1 && bqres.first[:ds].strip == rowfc[2]
|
114
|
+
end
|
115
|
+
|
116
|
+
# @return [Boolean] linha folha calculo existe parecida no bigquery?
|
117
|
+
def linha_simila?
|
118
|
+
bqres.count == 1 && bqres.first[:ds].strip != rowfc[2]
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [String] sql para movimentos no bigquery
|
122
|
+
def sql_existe_mv
|
123
|
+
"select *,#{ky_mv} as ky from hernanilr.ab.mv " \
|
124
|
+
"where nc=#{conta} and dl='#{rowfc[0].strftime(DF)}' and vl=#{rowfc[3]}"
|
125
|
+
end
|
126
|
+
|
127
|
+
# obtem movimento (values.mv) para inserir
|
128
|
+
#
|
129
|
+
# @return [String] ' NOVO'
|
130
|
+
def values_mv
|
131
|
+
@mvvls += ",('#{rowfc[0].strftime(DF)}','#{dvc.strftime(DF)}','#{rowfc[2]}',#{rowfc[3]}" + values_mv_extra
|
132
|
+
' NOVO'
|
133
|
+
end
|
134
|
+
|
135
|
+
# @return [String] campos extra do movimento (values.mv) para inserir
|
136
|
+
def values_mv_extra
|
137
|
+
",#{conta},#{dvc.year},#{dvc.month},'#{tpc}',#{ctc})"
|
138
|
+
end
|
139
|
+
|
140
|
+
# @return [Date] data valor corrigida
|
141
|
+
def dvc
|
142
|
+
opcao[:v].size.zero? ? rowfc[1] : Date.parse(opcao[:v])
|
143
|
+
end
|
144
|
+
|
145
|
+
# @return [String] classificacao do movimento (null --> classificacao automatica)
|
146
|
+
def ctc
|
147
|
+
opcao[:g].size.zero? ? 'null' : ("'" + opcao[:g] + "'")
|
148
|
+
end
|
149
|
+
|
150
|
+
# @return [String] tipo movimento c[redito] ou d[ebito]
|
151
|
+
def tpc
|
152
|
+
rowfc[3].positive? ? 'c' : 'd'
|
153
|
+
end
|
154
|
+
end
|
data/lib/abank/rendas.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @see Abank::Big
|
4
|
+
class Abank::Big
|
5
|
+
# @return [Integer] ano renda em tratamento
|
6
|
+
attr_reader :reano
|
7
|
+
|
8
|
+
# @return [Integer] mes renda em tratamento
|
9
|
+
attr_reader :repos
|
10
|
+
|
11
|
+
# @return [Float] valor renda mensal
|
12
|
+
attr_reader :revre
|
13
|
+
|
14
|
+
# @return [String] rendas a inserir (values.re)
|
15
|
+
attr_reader :revls
|
16
|
+
|
17
|
+
# @return [Integer] movimento em tratamento
|
18
|
+
attr_reader :mvpos
|
19
|
+
|
20
|
+
# @return [Date] data lancamento movimento em tratamento
|
21
|
+
attr_reader :mvdlm
|
22
|
+
|
23
|
+
# @return [Float] valor movimento em tratamento
|
24
|
+
attr_reader :mvvlm
|
25
|
+
|
26
|
+
# (see CLI#recriare)
|
27
|
+
def re_atualiza
|
28
|
+
# obtem contratos ativos
|
29
|
+
@ctlct = sel('SELECT ct from hernanilr.ab.re group by 1')
|
30
|
+
|
31
|
+
# [re]cria rendas [novas|todas]
|
32
|
+
lr_apaga.cm_cria.vr_cria.re_insert
|
33
|
+
end
|
34
|
+
|
35
|
+
# cria rendas associadas a lista ids contratos arrendamento
|
36
|
+
def re_work
|
37
|
+
bqnrs.zero? || ctlct.count.positive? ? cm_cria.vr_cria.re_insert : re_atualiza
|
38
|
+
end
|
39
|
+
|
40
|
+
# obtem rendas a inserir (values.re)
|
41
|
+
#
|
42
|
+
# @return [Big] acesso a base dados abank no bigquery
|
43
|
+
def vr_cria
|
44
|
+
@revls = ctlcm.map { |c| rendas_novas(c) }.flatten(1).join(',')
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# insere rendas no bigquery
|
49
|
+
def re_insert
|
50
|
+
if revls.size.zero?
|
51
|
+
puts 'NAO EXISTEM RENDAS NOVAS'
|
52
|
+
else
|
53
|
+
dml('insert hernanilr.ab.re VALUES' + revls)
|
54
|
+
puts "RENDAS #{str_lc('')} CRIADAS " + bqnrs.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param [Hash] cmv dados contrato arrendamento (inclui lista movimentos novos)
|
59
|
+
# @return [Array<String>] lista rendas novas dum contrato arrendamento (values.re)
|
60
|
+
def rendas_novas(cmv)
|
61
|
+
return [] unless cmv[:mv].count.positive?
|
62
|
+
|
63
|
+
vars_re(cmv)
|
64
|
+
r = []
|
65
|
+
while mvvlm >= revre && mvpos < cmv[:mv].count
|
66
|
+
r << nova_re(cmv)
|
67
|
+
proximo_mv(cmv)
|
68
|
+
end
|
69
|
+
r
|
70
|
+
end
|
71
|
+
|
72
|
+
# inicializa variaveis para processar rendas do contrato arrendamento
|
73
|
+
# @param (see rendas_novas)
|
74
|
+
def vars_re(cmv)
|
75
|
+
@reano = cmv[:ano]
|
76
|
+
@repos = cmv[:cnt]
|
77
|
+
@revre = Float(cmv[:ct][/\d+/]) / 100
|
78
|
+
@mvpos = 0
|
79
|
+
vars_re_mv(cmv)
|
80
|
+
end
|
81
|
+
|
82
|
+
# inicializa variaveis para processar movimentos associados ao contrato arrendamento
|
83
|
+
# @param (see rendas_novas)
|
84
|
+
def vars_re_mv(cmv)
|
85
|
+
@mvdlm = cmv[:mv][mvpos][:dl]
|
86
|
+
@mvvlm = cmv[:mv][mvpos][:vl]
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param (see rendas_novas)
|
90
|
+
# @return [String] renda formatada (values.re)
|
91
|
+
def nova_re(cmv)
|
92
|
+
# inicializa proxima renda
|
93
|
+
if repos == 12
|
94
|
+
@repos = 1
|
95
|
+
@reano += 1
|
96
|
+
else
|
97
|
+
@repos += 1
|
98
|
+
end
|
99
|
+
"('#{cmv[:ct]}',#{reano},#{repos},'#{mvdlm.strftime(DF)}',#{dias(cmv)})"
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param (see rendas_novas)
|
103
|
+
# @return [Integer] dias atraso no pagamento da renda
|
104
|
+
def dias(cmv)
|
105
|
+
mvdlm.mjd - (Date.new(reano, repos, 1) >> (cmv[:dc].month - 1)).mjd
|
106
|
+
end
|
107
|
+
|
108
|
+
# inicializa variaveis para processar proximo movimento
|
109
|
+
# @param (see rendas_novas)
|
110
|
+
def proximo_mv(cmv)
|
111
|
+
# valor renda paga retirado do valor do movimento
|
112
|
+
@mvvlm -= revre
|
113
|
+
return unless mvvlm < revre
|
114
|
+
|
115
|
+
# avanca na lista de movimentos
|
116
|
+
@mvpos += 1
|
117
|
+
return unless mvpos < cmv[:mv].count
|
118
|
+
|
119
|
+
vars_re_mv(cmv)
|
120
|
+
end
|
121
|
+
end
|
data/lib/abank/version.rb
CHANGED
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.
|
4
|
+
version: 0.2.5
|
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-
|
11
|
+
date: 2020-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,9 +94,9 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description: Arquiva
|
98
|
-
apagar movimentos
|
99
|
-
|
97
|
+
description: Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery.
|
98
|
+
Permite apagar/recriar movimentos/rendas ja no bigquery. Permite ainda classificar
|
99
|
+
movimentos no bigquery.
|
100
100
|
email:
|
101
101
|
- hernanirvaz@gmail.com
|
102
102
|
executables:
|
@@ -105,6 +105,7 @@ extensions: []
|
|
105
105
|
extra_rdoc_files: []
|
106
106
|
files:
|
107
107
|
- ".gitignore"
|
108
|
+
- ".rubocop.yml"
|
108
109
|
- ".travis.yml"
|
109
110
|
- Gemfile
|
110
111
|
- Gemfile.lock
|
@@ -116,8 +117,10 @@ files:
|
|
116
117
|
- bin/setup
|
117
118
|
- exe/abank
|
118
119
|
- lib/abank.rb
|
119
|
-
- lib/abank/
|
120
|
-
- lib/abank/
|
120
|
+
- lib/abank/big.rb
|
121
|
+
- lib/abank/contrato.rb
|
122
|
+
- lib/abank/folha.rb
|
123
|
+
- lib/abank/rendas.rb
|
121
124
|
- lib/abank/version.rb
|
122
125
|
homepage: https://github.com/hernanirvaz/abank
|
123
126
|
licenses:
|
@@ -140,8 +143,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
143
|
- !ruby/object:Gem::Version
|
141
144
|
version: '0'
|
142
145
|
requirements: []
|
143
|
-
rubygems_version: 3.0.
|
146
|
+
rubygems_version: 3.0.8
|
144
147
|
signing_key:
|
145
148
|
specification_version: 4
|
146
|
-
summary: Arquiva
|
149
|
+
summary: Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery.
|
147
150
|
test_files: []
|
data/lib/abank/bigquery.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'roo'
|
4
|
-
require 'google/cloud/bigquery'
|
5
|
-
|
6
|
-
module Abank
|
7
|
-
DF = '%Y-%m-%d'
|
8
|
-
|
9
|
-
# (see Bigquery)
|
10
|
-
class Bigquery
|
11
|
-
# @return [Google::Cloud::Bigquery] API bigquery
|
12
|
-
attr_reader :apibq
|
13
|
-
# @return [Roo::Excelx] folha calculo a processar
|
14
|
-
attr_reader :folha
|
15
|
-
# @return [Hash<Symbol, Boolean>] opcoes trabalho com linhas
|
16
|
-
attr_reader :linha
|
17
|
-
# @return [Integer] numero conta
|
18
|
-
attr_reader :conta
|
19
|
-
|
20
|
-
# @return [Array] row folha calculo em processamento
|
21
|
-
attr_reader :row
|
22
|
-
# @return [Google::Cloud::Bigquery::QueryJob] job bigquery
|
23
|
-
attr_reader :job
|
24
|
-
# @return (see sql_select)
|
25
|
-
attr_reader :sql
|
26
|
-
|
27
|
-
# @param [String] xls folha calculo para processar
|
28
|
-
# @param [Hash<Symbol, Boolean>] ops opcoes trabalho com linhas
|
29
|
-
# @option ops [Boolean] :s (false) apaga linha similar?
|
30
|
-
# @option ops [Boolean] :e (false) apaga linha igual?
|
31
|
-
# @option ops [Boolean] :m (false) apaga linhas existencia multipla?
|
32
|
-
# @option ops [Boolean] :i (false) insere linha nova?
|
33
|
-
# @return [Bigquery] acesso folhas calculo activobank
|
34
|
-
# & correspondente bigquery dataset
|
35
|
-
def initialize(xls = '', ops = { s: false, e: false, m: false, i: false })
|
36
|
-
# usa env GOOGLE_APPLICATION_CREDENTIALS para obter credentials
|
37
|
-
# @see https://cloud.google.com/bigquery/docs/authentication/getting-started
|
38
|
-
@apibq = Google::Cloud::Bigquery.new
|
39
|
-
@folha = Roo::Spreadsheet.open(xls) if xls.size.positive?
|
40
|
-
@linha = ops
|
41
|
-
@conta = xls.match?(/card/i) ? 2 : 1
|
42
|
-
end
|
43
|
-
|
44
|
-
# cria job bigquery & verifica execucao
|
45
|
-
#
|
46
|
-
# @param [String] sql a executar
|
47
|
-
# @return [Boolean] job ok?
|
48
|
-
def job_bigquery?(sql)
|
49
|
-
@job = apibq.query_job(sql)
|
50
|
-
@job.wait_until_done!
|
51
|
-
puts @job.error['message'] if @job.failed?
|
52
|
-
@job.failed?
|
53
|
-
end
|
54
|
-
|
55
|
-
# cria Data Manipulation Language (DML) job bigquery
|
56
|
-
#
|
57
|
-
# @param (see job_bigquery?)
|
58
|
-
# @return [Integer] numero linhas afetadas
|
59
|
-
def dml(sql)
|
60
|
-
job_bigquery?(sql) ? 0 : job.num_dml_affected_rows
|
61
|
-
end
|
62
|
-
|
63
|
-
# pesquisa existencia linha folha calculo no bigquery
|
64
|
-
#
|
65
|
-
# @return [Google::Cloud::Bigquery::Data] resultado do sql num array<hash>
|
66
|
-
def sql_select
|
67
|
-
# array.count = 0 ==> pode carregar esta linha
|
68
|
-
# array.count = 1 ==> mais testes necessarios
|
69
|
-
# array.count > 1 ==> nao carregar esta linha
|
70
|
-
@sql = job_bigquery?('select * ' + sql_where) ? [{}, {}] : job.data
|
71
|
-
end
|
72
|
-
|
73
|
-
# @return [String] parte sql para processamento linhas similares
|
74
|
-
def sql_where
|
75
|
-
"from hernanilr.ab.mv where nc=#{conta}" \
|
76
|
-
" and dl='#{row[0].strftime(DF)}'" \
|
77
|
-
" and vl=#{row[3]}"
|
78
|
-
end
|
79
|
-
|
80
|
-
# (see CLI#classifica)
|
81
|
-
def classifica
|
82
|
-
return unless linha[:i]
|
83
|
-
|
84
|
-
puts 'LINHAS CLASSIFICADAS ' +
|
85
|
-
dml('update hernanilr.ab.mv set mv.ct=tt.nct' \
|
86
|
-
' from (select * from hernanilr.ab.cl) as tt' \
|
87
|
-
' where mv.dl=tt.dl and mv.dv=tt.dv' \
|
88
|
-
' and mv.ds=tt.ds and mv.vl=tt.vl').to_s
|
89
|
-
end
|
90
|
-
|
91
|
-
# @return [Integer] numero linhas inseridas
|
92
|
-
def sql_insert
|
93
|
-
return 1 unless linha[:i]
|
94
|
-
|
95
|
-
dml('insert hernanilr.ab.mv(dl,dv,ds,vl,nc,ano,mes,ct,tp) VALUES(' \
|
96
|
-
"'#{row[0].strftime(DF)}','#{row[1].strftime(DF)}','#{row[2]}'" +
|
97
|
-
str_insert1)
|
98
|
-
end
|
99
|
-
|
100
|
-
# @return [String] campos extra da linha bigquery
|
101
|
-
def str_insert1
|
102
|
-
",#{row[3]},#{conta}" + str_insert2
|
103
|
-
end
|
104
|
-
|
105
|
-
# @return [String] campos calculados da linha bigquery
|
106
|
-
def str_insert2
|
107
|
-
",#{row[1].year},#{row[1].month},null,'#{row[3].positive? ? 'c' : 'd'}')"
|
108
|
-
end
|
109
|
-
|
110
|
-
# @return [Integer] numero linhas apagadas
|
111
|
-
def sql_delete
|
112
|
-
dml('delete ' + sql_where + " and ds='#{sql.first[:ds].strip}'")
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
data/lib/abank/folhacalculo.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Abank
|
4
|
-
HT = ['Data Lanc.', 'Data Valor', 'Descrição', 'Valor'].freeze
|
5
|
-
RF = '%<v3>-35.35s %<v4>8.2f'
|
6
|
-
|
7
|
-
# classifica & arquiva dados das folhas calculo activobank no bigquery
|
8
|
-
class Bigquery
|
9
|
-
# corrige linha folha calculo para processamento
|
10
|
-
#
|
11
|
-
# @param [Hash] has da linha em processamento
|
12
|
-
def corrige_hash(has)
|
13
|
-
@row = has.values
|
14
|
-
@row[2] = row[2].strip
|
15
|
-
@row[3] = -1 * row[3] if conta > 1
|
16
|
-
end
|
17
|
-
|
18
|
-
# processa linhas folha calculo & classifica bigquery
|
19
|
-
def processa
|
20
|
-
n = 0
|
21
|
-
folha.sheet(0).parse(header_search: HT) do |r|
|
22
|
-
n += 1
|
23
|
-
puts n == 1 ? "\n" + folha.info : processa_row(r)
|
24
|
-
end
|
25
|
-
classifica
|
26
|
-
end
|
27
|
-
|
28
|
-
# processa linha folha calculo para arquivo
|
29
|
-
#
|
30
|
-
# @param (see corrige_hash)
|
31
|
-
# @return [String] texto informativo do processamento
|
32
|
-
def processa_row(has)
|
33
|
-
corrige_hash(has)
|
34
|
-
sql_select
|
35
|
-
if row_naoexiste? then row_str + (sql_insert == 1 ? ' NOVA' : ' ERRO')
|
36
|
-
elsif row_simila? then row_similar
|
37
|
-
elsif row_existe? then row_existente
|
38
|
-
else row_multiplas
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# @return [String] linha folha calculo formatada
|
43
|
-
def row_str
|
44
|
-
"#{row[0].strftime(DF)} #{row[1].strftime(DF)} " \
|
45
|
-
"#{format(RF, v3: row[2], v4: row[3])}"
|
46
|
-
end
|
47
|
-
|
48
|
-
# @return [String] linha folha calculo similar
|
49
|
-
def row_similar
|
50
|
-
d = linha[:s] ? sql_delete : 0
|
51
|
-
row_str + ' SIMILAR' + str_apagadas(d) + sql.first[:ds].strip
|
52
|
-
end
|
53
|
-
|
54
|
-
# @return [String] linha folha calculo existente
|
55
|
-
def row_existente
|
56
|
-
d = linha[:e] ? sql_delete : 0
|
57
|
-
row_str + ' EXISTENTE' + str_apagadas(d)
|
58
|
-
end
|
59
|
-
|
60
|
-
# @return [String] linha folha calculo existencia multipla
|
61
|
-
def row_multiplas
|
62
|
-
d = linha[:m] ? sql_delete : 0
|
63
|
-
row_str + ' MULTIPLAS ' + sql.count.to_s + str_apagadas(d)
|
64
|
-
end
|
65
|
-
|
66
|
-
# @param [Integer] numero linhas apagadas
|
67
|
-
# @return [String] texto formatado linhas apagadas
|
68
|
-
def str_apagadas(num)
|
69
|
-
num.positive? ? ' & ' + num.to_s + ' APAGADA(S) ' : ' '
|
70
|
-
end
|
71
|
-
|
72
|
-
# @return [Boolean] linha folha calculo nao existe no bigquery?
|
73
|
-
def row_naoexiste?
|
74
|
-
sql.count.zero?
|
75
|
-
end
|
76
|
-
|
77
|
-
# @return [Boolean] linha folha calculo existe no bigquery?
|
78
|
-
def row_existe?
|
79
|
-
sql.count == 1 && sql.first[:ds].strip == row[2]
|
80
|
-
end
|
81
|
-
|
82
|
-
# @return [Boolean] linha folha calculo existe parecida no bigquery?
|
83
|
-
def row_simila?
|
84
|
-
sql.count == 1 && sql.first[:ds].strip != row[2]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|