abank 0.2.3 → 0.2.9

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: 90945827ff39ea567dd16f073018ef56215da38498e9ca317a2aff12a23e9a6d
4
- data.tar.gz: a2797459015e62c0a3bacc5eb2897ca58b52be346d885ce2494d9dd81cc08ba0
3
+ metadata.gz: 36171477026334dbce5da50183c84e693047db8fb387c1306308f254590793fc
4
+ data.tar.gz: da568eeb037c6deb414981abed805596ae1034f94eee103948bfdec5da958734
5
5
  SHA512:
6
- metadata.gz: 87b7130b7a34943a80dad48903c083b5a06074f35d951575d435d4c4f58a466141bf0ef3021bca22515110e14cd179c64d7991292207d1fb029e309832d3258b
7
- data.tar.gz: 48562e6cdae584b35bacea3c9a7ab5149922c244fe1b6248b57527577c288675e2da1b9eb082e7bd5ee9bb075b26199a34368e52cc3a3d18bcf575e9369fd6c7
6
+ metadata.gz: a9fbda092cf84a6ee8a2552fbd0ff363d482fd599a243d263d03374978e6ab819cfcd270dc3d0c67456c4b54ddcc126d161e45180888a38922d1a4d468dbfe35
7
+ data.tar.gz: 69365abb9979d7ca48369451c8496708cee0d15a3f4a0ef73521daa608c0c9c94a67ce2e5a00c4f2656c40ed4b1386d3224ea26b2094a6879bb87f03b6a14b1f
@@ -0,0 +1,15 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ EnabledByDefault: true
4
+
5
+ Style/Copyright:
6
+ Enabled: false
7
+
8
+ Lint/ConstantResolution:
9
+ Enabled: false
10
+
11
+ Style/ConstantVisibility:
12
+ Enabled: false
13
+
14
+ Style/EmptyElse:
15
+ EnforcedStyle: nil
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in abank.gemspec
4
6
  gemspec
5
7
 
6
- gem "rake", "~> 12.0"
8
+ gem 'rake', '~> 12.0'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abank (0.2.3)
4
+ abank (0.2.9)
5
5
  google-cloud-bigquery
6
6
  roo
7
7
  thor
@@ -12,12 +12,12 @@ GEM
12
12
  specs:
13
13
  addressable (2.7.0)
14
14
  public_suffix (>= 2.0.2, < 5.0)
15
- concurrent-ruby (1.1.6)
16
- declarative (0.0.10)
15
+ concurrent-ruby (1.1.7)
16
+ declarative (0.0.20)
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.39.3)
20
+ google-api-client (0.43.0)
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.0)
28
+ google-cloud-bigquery (1.21.2)
29
29
  concurrent-ruby (~> 1.0)
30
30
  google-api-client (~> 0.33)
31
31
  google-cloud-core (~> 1.2)
@@ -34,10 +34,10 @@ 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.1)
37
+ google-cloud-env (1.3.3)
38
38
  faraday (>= 0.17.3, < 2.0)
39
- google-cloud-errors (1.0.0)
40
- googleauth (0.12.0)
39
+ google-cloud-errors (1.0.1)
40
+ googleauth (0.13.1)
41
41
  faraday (>= 0.17.3, < 2.0)
42
42
  jwt (>= 1.4, < 3.0)
43
43
  memoist (~> 0.16)
@@ -45,15 +45,15 @@ GEM
45
45
  os (>= 0.9, < 2.0)
46
46
  signet (~> 0.14)
47
47
  httpclient (2.8.3)
48
- jwt (2.2.1)
48
+ jwt (2.2.2)
49
49
  memoist (0.16.2)
50
50
  mini_mime (1.0.2)
51
51
  mini_portile2 (2.4.0)
52
- multi_json (1.14.1)
52
+ multi_json (1.15.0)
53
53
  multipart-post (2.1.1)
54
- nokogiri (1.10.9)
54
+ nokogiri (1.10.10)
55
55
  mini_portile2 (~> 2.4.0)
56
- os (1.1.0)
56
+ os (1.1.1)
57
57
  public_suffix (4.0.5)
58
58
  rake (12.3.3)
59
59
  representable (3.0.4)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Abank [![Build Status](https://travis-ci.com/hernanirvaz/abank.svg?branch=master)](https://travis-ci.com/hernanirvaz/abank)
2
2
 
3
- Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery. Permite apagar movimentos similares/existentes ja no bigquery. Permite ainda classificar movimentos ja no bigquery.
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 help [COMANDO] # ajuda aos comandos
24
- $ abank mostra # mostra dados da folha calculo
25
- $ abank load # carrega dados da folha calculo no bigquery
26
- $ abank classifica # classifica arquivo no bigquery
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
@@ -1,2 +1,4 @@
1
- require "bundler/gem_tasks"
2
- task :default => :build
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ task default: :build
@@ -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 <conta-corrente>.xlsx,' \
14
- ' <conta-cartao>.xlsx no bigquery.'
15
- spec.description = spec.summary +
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 = Dir.chdir(File.expand_path(__dir__)) do
28
- `git ls-files -z`.split("\x0")
29
- .reject { |f| f.match(%r{^(test|spec|features)/}) }
30
- end
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']
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "abank"
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 "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -1,90 +1,95 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'thor'
4
- require 'abank/bigquery'
5
- require 'abank/folhacalculo'
6
- require 'abank/version'
3
+ require('thor')
4
+ require('abank/big')
5
+ require('abank/contrato')
6
+ require('abank/rendas')
7
+ require('abank/folha')
8
+ require('abank/version')
7
9
 
8
10
  # @author Hernani Rodrigues Vaz
9
11
  module Abank
10
- ID = `whoami`.chomp
12
+ DR = "/home/#{`whoami`.chomp}/Downloads"
13
+ BD = 'hernanilr.ab'
11
14
 
12
15
  class Error < StandardError; end
13
16
 
14
17
  # CLI para carregar folhas calculo comuns no bigquery
15
18
  class CLI < Thor
16
- desc 'load', 'carrega dados da folha calculo no bigquery'
17
- option :d, banner: 'DIR', default: "/home/#{ID}/Downloads",
18
- desc: 'Onde procurar folhas calculo'
19
- option :x, banner: 'EXT', default: '.xlsx',
20
- desc: 'Extensao das folhas calculo'
21
- option :n, banner: 'NUM', type: :numeric, default: 0,
22
- desc: 'Correcao dias para data valor'
23
- option :s, type: :boolean, default: false,
24
- desc: 'apaga linha similar no bigquery'
25
- option :e, type: :boolean, default: false,
26
- desc: 'apaga linha igual no bigquery'
27
- option :m, type: :boolean, default: false,
28
- desc: 'apaga linhas existencia multipla no bigquery'
29
- # processa folha calculo
30
- def load
31
- Dir.glob("#{options[:d]}/*#{options[:x]}").sort.each do |f|
32
- Bigquery.new(f, load_ops).processa
33
- end
19
+ desc 'tag', 'classifica movimentos'
20
+ # classifica movimentos
21
+ def tag
22
+ Big.new.mv_classifica
34
23
  end
35
24
 
36
- desc 'mostra', 'mostra dados da folha calculo'
37
- option :d, banner: 'DIR', default: "/home/#{ID}/Downloads",
38
- desc: 'Onde procurar folhas calculo'
39
- option :x, banner: 'EXT', default: '.xlsx',
40
- desc: 'Extensao das folhas calculo'
41
- # mostra folha calculo
42
- def mostra
43
- Dir.glob("#{options[:d]}/*#{options[:x]}").sort.each do |f|
44
- Bigquery.new(f).processa
45
- end
25
+ desc 'apagamv', 'apaga movimentos'
26
+ option :k, banner: 'KEY[,KEY...]', required: true, desc: 'keys movimentos a apagar'
27
+ # apaga movimentos
28
+ def apagamv
29
+ Big.new(k: options[:k]).mv_delete.mv_insert.re_work
30
+ end
31
+
32
+ desc 'criact', 'cria contrato arrendamento'
33
+ option :c, banner: 'CONTRATO', required: true, desc: 'Identificador contrato arrendamento'
34
+ option :t, type: :boolean, default: true, desc: 'cria todas as rendas?'
35
+ option :d, banner: 'DATA', default: '', desc: 'data contrato arrendamento'
36
+ # cria contrato arrendamento
37
+ def criact
38
+ Big.new(c: options[:c], t: options[:t], d: options[:d]).ct_cria
46
39
  end
47
40
 
48
- desc 'classifica', 'classifica movimentos no bigquery'
49
- # classifica movimentos no bigquery
50
- def classifica
51
- Bigquery.new('', { i: true }).classifica
41
+ desc 'apagact', 'apaga contrato arrendamento'
42
+ option :c, banner: 'CONTRATO', required: true, desc: 'Identificador contrato arrendamento'
43
+ option :t, type: :boolean, default: false, desc: 'apaga todas as rendas?'
44
+ # apaga contrato arrendamento
45
+ def apagact
46
+ Big.new(c: options[:c], t: options[:t]).ct_apaga
52
47
  end
53
48
 
54
- desc 'atualiza', 'atualiza rendas no arquivo bigquery'
55
- # atualiza rendas no arquivo bigquery
56
- def atualiza
57
- Bigquery.new.atualiza
49
+ desc 'recriact', 'atualiza rendas de contrato arrendamento'
50
+ option :c, banner: 'CONTRATO', required: true, desc: 'Identificador contrato arrendamento'
51
+ option :t, type: :boolean, default: false, desc: 'apaga todas as rendas?'
52
+ option :d, banner: 'DATA', default: '', desc: 'data contrato arrendamento'
53
+ # atualiza rendas de contrato arrendamento
54
+ def recriact
55
+ Big.new(c: options[:c], t: options[:t]).ct_apaga
56
+ Big.new(c: options[:c], t: true, d: options[:d]).ct_cria
58
57
  end
59
58
 
60
- desc 'cria', 'cria contrato arrendamento/rendas no arquivo bigquery'
61
- option :r, banner: 'REN', required: true,
62
- desc: 'identificador contrato arrendamento a criar'
63
- option :t, type: :boolean, default: false,
64
- desc: 'trabalha com renda inicio ou todas'
65
- # cria contrato arrendamento/rendas no arquivo bigquery
66
- def cria
67
- Bigquery.new('', { r: options[:r], t: options[:t] }).cria
59
+ desc 'recriare', 'atualiza rendas dos contratos ativos'
60
+ option :t, type: :boolean, default: false, desc: 'atualiza todas as rendas?'
61
+ # atualiza rendas dos contratos ativos
62
+ def recriare
63
+ Big.new(t: options[:t]).re_atualiza
68
64
  end
69
65
 
70
- desc 'apaga', 'apaga contrato arrendamento/rendas no arquivo bigquery'
71
- option :r, banner: 'REN', required: true,
72
- desc: 'identificador contrato arrendamento a apagar'
73
- option :t, type: :boolean, default: false,
74
- desc: 'trabalha com renda inicio ou todas'
75
- # apaga contrato arrendamento/rendas no arquivo bigquery
76
- def apaga
77
- Bigquery.new('', { r: options[:r], t: options[:t] }).apaga
66
+ desc 'work', 'carrega/apaga dados da folha calculo'
67
+ option :s, type: :boolean, default: false, desc: 'apaga movimento similar'
68
+ option :e, type: :boolean, default: false, desc: 'apaga movimento igual'
69
+ option :v, banner: 'DATA', default: '', desc: 'data valor para movimentos a carregar'
70
+ option :g, banner: 'TAG', default: '', desc: 'classificacao para movimentos a carregar'
71
+ # carrega/apaga dados da folha calculo
72
+ def work
73
+ Dir.glob("#{DR}/*.xlsx").sort.each do |f|
74
+ Folha.new(work_opc.merge(f: f)).processa_xls
75
+ end
76
+ end
77
+
78
+ desc 'show', 'mostra dados da folha calculo'
79
+ # mostra folha calculo
80
+ def show
81
+ Dir.glob("#{DR}/*.xlsx").sort.each do |f|
82
+ Folha.new(f: f).processa_xls
83
+ end
78
84
  end
79
85
 
80
86
  no_commands do
81
- # @return [Hash] ops opcoes trabalho com linhas para load
82
- def load_ops
83
- { s: options[:s], e: options[:e], m: options[:m],
84
- i: true, t: false, n: options[:n], r: '' }
87
+ # @return [Hash] opcoes trabalho com movimentos para work
88
+ def work_opc
89
+ { s: options[:s], e: options[:e], i: true, v: options[:v], g: options[:g] }
85
90
  end
86
91
  end
87
92
 
88
- default_task :mostra
93
+ default_task :show
89
94
  end
90
95
  end
@@ -0,0 +1,135 @@
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
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Abank
4
+ # acesso a base dados abank no bigquery
5
+ class Big
6
+ # @return [String] id contrato arrendamento
7
+ attr_reader :ctide
8
+
9
+ # @return [Array<Hash>] lista ids contratos arrendamento
10
+ # @example
11
+ # [{ ct: 'r03000' }, ...]
12
+ attr_reader :ctlct
13
+
14
+ # @return [Array<Hash>] lista dados contrato arrendamento (inclui lista movimentos novos)
15
+ # @example
16
+ # [{ct: 'r03000', dc: '2020-03-01', ano: 2020, cnt: 0, dl: '2020-03-01', mv: [{dl: '2020-03-02', vl: 30}, ...] }]
17
+ attr_reader :ctlcm
18
+
19
+ # (see CLI#criact)
20
+ def ct_cria
21
+ if existe_contrato?
22
+ @bqnrs = 1
23
+ puts('CONTRATO JA EXISTE')
24
+ else
25
+ dml("insert into #{BD}.re #{sql_contrato_mv}")
26
+ puts("CONTRATO #{ctide} " + (bqnrs.zero? ? 'NAO EXISTE' : 'INSERIDO'))
27
+ end
28
+ return unless existem_rendas?
29
+
30
+ # processa rendas associadas ao contrato arrendamento
31
+ cm_cria.vr_cria.re_insert
32
+ end
33
+
34
+ # (see CLI#apagact)
35
+ def ct_apaga
36
+ @ctlct = [{ ct: ctide }]
37
+ lc_apaga
38
+ end
39
+
40
+ # apaga rendas da lista de contrato arrendamento
41
+ #
42
+ # @return [Big] acesso a base dados abank no bigquery
43
+ def lr_apaga
44
+ return self unless opcao[:t] && ctlct.count.positive?
45
+
46
+ # para nao apagar contrato arrendamento - somente as rendas
47
+ @opcao[:t] = false
48
+
49
+ lc_apaga
50
+ self
51
+ end
52
+
53
+ # apaga rendas da lista de contratos arrendamento
54
+ def lc_apaga
55
+ dml("delete from #{BD}.re where ct in(#{str_lc})#{opcao[:t] ? '' : ' and cnt>0'}")
56
+ puts("RENDAS #{str_lc('')} APAGADAS " + bqnrs.to_s)
57
+ end
58
+
59
+ # @return [String] texto formatado que representa lista de contratos arrendamento
60
+ def str_lc(sep = "'")
61
+ ctlct.map { |c| sep + c[:ct] + sep }.join(',')
62
+ end
63
+
64
+ # optem lista dados contrato arrendamento (inclui lista movimentos novos)
65
+ #
66
+ # @return [Big] acesso a base dados abank no bigquery
67
+ def cm_cria
68
+ @ctlcm = []
69
+ ctlct.each do |c|
70
+ @ctide = c[:ct]
71
+ sql(sql_last_re)
72
+ @ctlcm << bqres[0].merge({ mv: sql(sql_novo_mv(bqres[0][:dl])) })
73
+ end
74
+ self
75
+ end
76
+
77
+ # @return [Boolean] existem rendas para processar sim/nao?
78
+ def existem_rendas?
79
+ @ctlct = [{ ct: ctide }]
80
+ bqnrs.positive? && opcao[:t]
81
+ end
82
+
83
+ # @return [Boolean] contrato arrendamento ja existe sim/nao?
84
+ def existe_contrato?
85
+ sql("select ct from #{BD}.re where ct='#{ctide}' and cnt=0").count.positive?
86
+ end
87
+
88
+ # @return [String] sql para obter ultima renda do contrato arrendamento
89
+ def sql_last_re
90
+ 'select ct,DATE_SUB(DATE_SUB(dl,INTERVAL dias DAY),INTERVAL IF(cnt=0,0,cnt-1) MONTH) as dc,ano,cnt,dl ' \
91
+ "from #{BD}.re where ct='#{ctide}' order by ano desc,cnt desc limit 1"
92
+ end
93
+
94
+ # @return [String] sql para obter movimentos novos (depois da ultima renda do contrato arrendamento)
95
+ def sql_novo_mv(mdl)
96
+ "select dl,vl from #{BD}.mv where ct='#{ctide}' and dl>='#{(mdl + 1).strftime(DF)}' order by dl,dv"
97
+ end
98
+
99
+ # @return [String] sql para obter dados do inicio contrato arrendamento
100
+ def sql_contrato_mv
101
+ if opcao[:d].size.zero?
102
+ 'select ct,EXTRACT(YEAR FROM DATE_TRUNC(dl,MONTH)) as ano,0 as cnt,DATE_TRUNC(dl,MONTH) as dl,0 dias ' \
103
+ "from #{BD}.mv where ct='#{ctide}' order by dl limit 1"
104
+ else
105
+ "select '#{ctide}' as ct,EXTRACT(YEAR FROM DATE '#{opcao[:d]}') as ano" \
106
+ ",0 as cnt,DATE '#{opcao[:d]}' as dl,0 dias"
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('roo')
4
+
5
+ module Abank
6
+ # acesso a folha calculo & base dados abank no bigquery
7
+ class Folha < Big
8
+ # @return [Roo::Excelx] folha calculo a processar
9
+ attr_reader :folha
10
+
11
+ # @return [Integer] numero conta associado a folha calculo
12
+ # @example
13
+ # mov*.xlsx --> 1 --> conta-corrente
14
+ # movCard*.xlsx --> 2 --> conta-cartao
15
+ attr_reader :conta
16
+
17
+ # @return [Array] row folha calculo em processamento
18
+ attr_reader :rowfc
19
+
20
+ # acesso a folha calculo & base dados abank no bigquery
21
+ #
22
+ # @param [Hash] opc opcoes trabalho
23
+ # @option opc [String] :f ('') folha calculo a processar
24
+ # @option opc [Boolean] :s (false) apaga movimento similar? (mv)
25
+ # @option opc [Boolean] :e (false) apaga movimento igual? (mv)
26
+ # @option opc [Boolean] :i (false) insere movimento novo? (mv)
27
+ # @option opc [String] :v ('') data valor movimentos (mv)
28
+ # @option opc [String] :g ('') classificacao movimentos (mv)
29
+ def initialize(opc = {})
30
+ @opcao = super
31
+ @folha = Roo::Spreadsheet.open(opc.fetch(:f))
32
+ @conta = opc.fetch(:f).match?(/card/i) ? 2 : 1
33
+ @opcao[:s] = opc.fetch(:s, false)
34
+ @opcao[:e] = opc.fetch(:e, false)
35
+ @opcao[:i] = opc.fetch(:i, false)
36
+ @opcao[:v] = opc.fetch(:v, '')
37
+ @opcao[:g] = opc.fetch(:g, '')
38
+ end
39
+
40
+ # carrega/mostra folha calculo
41
+ def processa_xls
42
+ n = 0
43
+ folha.sheet(0).parse(header_search: ['Data Lanc.', 'Data Valor', 'Descrição', 'Valor']) do |r|
44
+ n += 1
45
+ puts n == 1 ? "\n#{folha.info}" : processa_linha(r)
46
+ end
47
+ return unless opcao[:i]
48
+
49
+ # processa movimentos & atualiza rendas
50
+ mv_delete.mv_insert.re_work
51
+ end
52
+
53
+ # processa linha folha calculo
54
+ #
55
+ # @param [Hash] linha da folha calculo em processamento
56
+ # @return [String] texto informativo formatado da linha em processamento
57
+ def processa_linha(linha)
58
+ vars_xls(linha)
59
+ # pesquisa existencia linha folha calculo no bigquery
60
+ # array.count = 0 ==> pode carregar esta linha
61
+ # array.count = 1 ==> mais testes necessarios
62
+ # array.count > 1 ==> nao pode carregar esta linha
63
+ sql(sql_existe_mv, [{}, {}])
64
+ if linha_naoexiste? then linha_base + values_mv
65
+ elsif linha_existe? then linha_existe
66
+ elsif linha_simila? then linha_similar
67
+ else linha_multiplas
68
+ end
69
+ end
70
+
71
+ # inicializa variavel para processar linha folha calculo
72
+ #
73
+ # @param (see processa_linha)
74
+ def vars_xls(linha)
75
+ @rowfc = linha.values
76
+ @rowfc[2] = rowfc[2].strip
77
+ @rowfc[3] = -1 * rowfc[3] if conta > 1
78
+ end
79
+
80
+ # @return [String] texto base formatado para display
81
+ def linha_base
82
+ "#{rowfc[0].strftime(DF)} #{format('%<v3>-34.34s %<v4>8.2f', v3: rowfc[2], v4: rowfc[3])}"
83
+ end
84
+
85
+ # @return [String] texto linha existente formatada para display
86
+ def linha_existe
87
+ add_kys if opcao[:e]
88
+ "#{linha_base} EXIS #{format('%<v1>20d', v1: bqres.first[:ky])}"
89
+ end
90
+
91
+ # @return [String] texto linha similar formatada para display
92
+ def linha_similar
93
+ add_kys if opcao[:s]
94
+ "#{linha_base} SIMI #{format('%<v1>-20.20s', v1: bqres.first[:ds].strip)}"
95
+ end
96
+
97
+ # @return [String] texto linha existencia multipla formatada para display
98
+ def linha_multiplas
99
+ "#{linha_base} MULT(#{bqres.count})"
100
+ end
101
+
102
+ # obtem chaves movimento (keysin.mv) para apagar
103
+ def add_kys
104
+ bqres.each { |r| @mvkys += ",#{r[:ky]}" }
105
+ end
106
+
107
+ # @return [Boolean] linha folha calculo nao existe no bigquery?
108
+ def linha_naoexiste?
109
+ bqres.count.zero?
110
+ end
111
+
112
+ # @return [Boolean] linha folha calculo existe no bigquery?
113
+ def linha_existe?
114
+ bqres.count == 1 && bqres.first[:ds].strip == rowfc[2]
115
+ end
116
+
117
+ # @return [Boolean] linha folha calculo existe parecida no bigquery?
118
+ def linha_simila?
119
+ bqres.count == 1 && bqres.first[:ds].strip != rowfc[2]
120
+ end
121
+
122
+ # @return [String] sql para movimentos no bigquery
123
+ def sql_existe_mv
124
+ "select *,#{ky_mv} as ky from #{BD}.mv " \
125
+ "where nc=#{conta} and dl='#{rowfc[0].strftime(DF)}' and vl=#{rowfc[3]}"
126
+ end
127
+
128
+ # obtem movimento (values.mv) para inserir
129
+ #
130
+ # @return [String] ' NOVO'
131
+ def values_mv
132
+ @mvvls += ",('#{rowfc[0].strftime(DF)}','#{dvc.strftime(DF)}','#{rowfc[2]}',#{rowfc[3]}" + values_mv_extra
133
+ ' NOVO'
134
+ end
135
+
136
+ # @return [String] campos extra do movimento (values.mv) para inserir
137
+ def values_mv_extra
138
+ ",#{conta},#{dvc.year},#{dvc.month},'#{tpc}',#{ctc})"
139
+ end
140
+
141
+ # @return [Date] data valor corrigida
142
+ def dvc
143
+ opcao[:v].size.zero? ? rowfc[1] : Date.parse(opcao[:v])
144
+ end
145
+
146
+ # @return [String] classificacao do movimento (null --> classificacao automatica)
147
+ def ctc
148
+ opcao[:g].size.zero? ? 'null' : "'#{opcao[:g]}'"
149
+ end
150
+
151
+ # @return [String] tipo movimento c[redito] ou d[ebito]
152
+ def tpc
153
+ rowfc[3].positive? ? 'c' : 'd'
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Abank
4
+ # @see Big
5
+ class Big
6
+ # @return [Integer] ano renda em tratamento
7
+ attr_reader :reano
8
+
9
+ # @return [Integer] mes renda em tratamento
10
+ attr_reader :repos
11
+
12
+ # @return [Float] valor renda mensal
13
+ attr_reader :revre
14
+
15
+ # @return [String] rendas a inserir (values.re)
16
+ attr_reader :revls
17
+
18
+ # @return [Integer] movimento em tratamento
19
+ attr_reader :mvpos
20
+
21
+ # @return [Date] data lancamento movimento em tratamento
22
+ attr_reader :mvdlm
23
+
24
+ # @return [Float] valor movimento em tratamento
25
+ attr_reader :mvvlm
26
+
27
+ # (see CLI#recriare)
28
+ def re_atualiza
29
+ # obtem contratos ativos
30
+ @ctlct = sql("SELECT ct from #{BD}.re group by 1")
31
+
32
+ # [re]cria rendas [novas|todas]
33
+ lr_apaga.cm_cria.vr_cria.re_insert
34
+ end
35
+
36
+ # cria rendas associadas a lista ids contratos arrendamento
37
+ def re_work
38
+ bqnrs.zero? || ctlct.count.positive? ? cm_cria.vr_cria.re_insert : re_atualiza
39
+ end
40
+
41
+ # obtem rendas a inserir (values.re)
42
+ #
43
+ # @return [Big] acesso a base dados abank no bigquery
44
+ def vr_cria
45
+ @revls = ctlcm.map { |c| rendas_novas(c) }.flatten(1).join(',')
46
+ self
47
+ end
48
+
49
+ # insere rendas no bigquery
50
+ def re_insert
51
+ if revls.size.zero?
52
+ puts('NAO EXISTEM RENDAS NOVAS')
53
+ else
54
+ dml("insert #{BD}.re VALUES#{revls}")
55
+ puts("RENDAS #{str_lc('')} CRIADAS " + bqnrs.to_s)
56
+ end
57
+ end
58
+
59
+ # @param [Hash] cmv dados contrato arrendamento (inclui lista movimentos novos)
60
+ # @return [Array<String>] lista rendas novas dum contrato arrendamento (values.re)
61
+ def rendas_novas(cmv)
62
+ return [] unless cmv[:mv].count.positive?
63
+
64
+ vars_re(cmv)
65
+ r = []
66
+ while mvvlm >= revre && mvpos < cmv[:mv].count
67
+ r << nova_re(cmv)
68
+ proximo_mv(cmv)
69
+ end
70
+ r
71
+ end
72
+
73
+ # inicializa variaveis para processar rendas do contrato arrendamento
74
+ # @param (see rendas_novas)
75
+ def vars_re(cmv)
76
+ @reano = cmv[:ano]
77
+ @repos = cmv[:cnt]
78
+ @revre = Float(cmv[:ct][/\d+/]) / 100
79
+ @mvpos = 0
80
+ vars_re_mv(cmv)
81
+ end
82
+
83
+ # inicializa variaveis para processar movimentos associados ao contrato arrendamento
84
+ # @param (see rendas_novas)
85
+ def vars_re_mv(cmv)
86
+ @mvdlm = cmv[:mv][mvpos][:dl]
87
+ @mvvlm = cmv[:mv][mvpos][:vl]
88
+ end
89
+
90
+ # @param (see rendas_novas)
91
+ # @return [String] renda formatada (values.re)
92
+ def nova_re(cmv)
93
+ # inicializa proxima renda
94
+ if repos == 12
95
+ @repos = 1
96
+ @reano += 1
97
+ else
98
+ @repos += 1
99
+ end
100
+ "('#{cmv[:ct]}',#{reano},#{repos},'#{mvdlm.strftime(DF)}',#{dias(cmv)})"
101
+ end
102
+
103
+ # @param (see rendas_novas)
104
+ # @return [Integer] dias atraso no pagamento da renda
105
+ def dias(cmv)
106
+ mvdlm.mjd - (Date.new(reano, repos, 1) >> (cmv[:dc].month - 1)).mjd
107
+ end
108
+
109
+ # inicializa variaveis para processar proximo movimento
110
+ # @param (see rendas_novas)
111
+ def proximo_mv(cmv)
112
+ # valor renda paga retirado do valor do movimento
113
+ @mvvlm -= revre
114
+ return unless mvvlm < revre
115
+
116
+ # avanca na lista de movimentos
117
+ @mvpos += 1
118
+ return unless mvpos < cmv[:mv].count
119
+
120
+ vars_re_mv(cmv)
121
+ end
122
+ end
123
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Abank
4
- VERSION = '0.2.3'
4
+ VERSION = '0.2.9'
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.3
4
+ version: 0.2.9
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-05-17 00:00:00.000000000 Z
11
+ date: 2020-08-28 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 <conta-corrente>.xlsx, <conta-cartao>.xlsx no bigquery. Pode
98
- apagar movimentos similares/existentes ja no bigquery. Pode ainda classificar movimentos
99
- ja no bigquery.
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/bigquery.rb
120
- - lib/abank/folhacalculo.rb
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.3
146
+ rubygems_version: 3.1.2
144
147
  signing_key:
145
148
  specification_version: 4
146
- summary: Arquiva <conta-corrente>.xlsx, <conta-cartao>.xlsx no bigquery.
149
+ summary: Arquiva movimentos conta-corrente, conta-cartao do activobank no bigquery.
147
150
  test_files: []
@@ -1,176 +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] 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] 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
- # @option ops [Boolean] :t (false) apaga rendas totalmente?
34
- # @option ops [Numeric] :n (0) numero dias correcao para data valor
35
- # @option ops [String] :r identificador contrato arrendamento
36
- # @return [Bigquery] acesso folhas calculo activobank
37
- # & correspondente bigquery dataset
38
- def initialize(xls = '', ops = { s: false, e: false, m: false,
39
- i: false, t: false, n: 0, r: '' })
40
- # usa env GOOGLE_APPLICATION_CREDENTIALS para obter credentials
41
- # @see https://cloud.google.com/bigquery/docs/authentication/getting-started
42
- @apibq = Google::Cloud::Bigquery.new
43
- @folha = Roo::Spreadsheet.open(xls) if xls.size.positive?
44
- @linha = ops
45
- @conta = xls.match?(/card/i) ? 2 : 1
46
- end
47
-
48
- # cria job bigquery & verifica execucao
49
- #
50
- # @param [String] sql a executar
51
- # @return [Boolean] job ok?
52
- def job_bigquery?(sql)
53
- @job = apibq.query_job(sql)
54
- @job.wait_until_done!
55
- puts @job.error['message'] if @job.failed?
56
- @job.failed?
57
- end
58
-
59
- # executa Stored procedure (SP) job bigquery
60
- #
61
- # @param (see job_bigquery?)
62
- # @return (see num_insert)
63
- def esp(sql)
64
- job_bigquery?(sql) ? 0 : num_insert(apibq.jobs(parent_job: job))
65
- end
66
-
67
- # @return [Integer] numero linhas inseridas
68
- def num_insert(sps)
69
- sps.find { |j| j.statement_type == 'INSERT' }.num_dml_affected_rows
70
- end
71
-
72
- # cria Data Manipulation Language (DML) job bigquery
73
- #
74
- # @param (see job_bigquery?)
75
- # @return [Integer] numero linhas afetadas
76
- def dml(sql)
77
- p sql
78
- job_bigquery?(sql) ? 0 : job.num_dml_affected_rows
79
- end
80
-
81
- # pesquisa existencia linha folha calculo no bigquery
82
- #
83
- # @return [Google::Cloud::Bigquery::Data] resultado do sql num array<hash>
84
- def sql_select
85
- # array.count = 0 ==> pode carregar esta linha
86
- # array.count = 1 ==> mais testes necessarios
87
- # array.count > 1 ==> nao carregar esta linha
88
- @sql = job_bigquery?('select * ' + sql_where) ? [{}, {}] : job.data
89
- end
90
-
91
- # @return [String] parte sql para processamento linhas similares
92
- def sql_where
93
- "from hernanilr.ab.mv where nc=#{conta}" \
94
- " and dl='#{row[0].strftime(DF)}'" \
95
- " and vl=#{row[3]}"
96
- end
97
-
98
- # (see CLI#classifica)
99
- def classifica
100
- return unless linha[:i]
101
-
102
- i = dml('update hernanilr.ab.mv set mv.ct=tt.nct' \
103
- ' from (select * from hernanilr.ab.cl) as tt' \
104
- ' where mv.dl=tt.dl and mv.dv=tt.dv' \
105
- ' and mv.ds=tt.ds and mv.vl=tt.vl')
106
- puts 'LINHAS CLASSIFICADAS ' + i.to_s
107
- return unless i.positive?
108
-
109
- atualiza
110
- end
111
-
112
- # (see CLI#atualiza)
113
- def atualiza
114
- puts 'RENDAS INSERIDAS ' + esp('call hernanilr.ab.rendas()').to_s
115
- end
116
-
117
- # (see CLI#cria)
118
- def cria
119
- i = dml('insert into hernanilr.ab.re ' + sql_contrato)
120
- puts i.zero? ? 'NAO EXISTE CONTRATO' : 'CONTRATO INSERIDO'
121
- return unless i.positive? && linha[:t]
122
-
123
- atualiza
124
- end
125
-
126
- # @return [String] sql obtem dados inicio contrato arrendamento
127
- def sql_contrato
128
- 'select ct,EXTRACT(YEAR FROM DATE_TRUNC(dl,MONTH)) as ano,0 as cnt' \
129
- ',DATE_TRUNC(dl,MONTH) as dl,0 dias' \
130
- ' from hernanilr.ab.mv' \
131
- " where ct='#{linha[:r]}' " \
132
- 'order by dl limit 1'
133
- end
134
-
135
- # (see CLI#apaga)
136
- def apaga
137
- puts 'RENDAS APAGADAS ' + dml(sql_apaga).to_s
138
- end
139
-
140
- # @return [String] sql apaga rendas
141
- def sql_apaga
142
- "delete from hernanilr.ab.re where ct='#{linha[:r]}'" +
143
- (linha[:t] ? '' : ' and cnt>0')
144
- end
145
-
146
- # @return [Integer] numero linhas inseridas
147
- def sql_insert
148
- return 1 unless linha[:i]
149
-
150
- dml('insert hernanilr.ab.mv(dl,dv,ds,vl,nc,ano,mes,ct,tp) VALUES(' \
151
- "'#{row[0].strftime(DF)}','#{data_valor.strftime(DF)}','#{row[2]}'" +
152
- str_insert1)
153
- end
154
-
155
- # @return [Date] data valor corrigida
156
- def data_valor
157
- row[1] + linha[:n].to_i
158
- end
159
-
160
- # @return [String] campos extra da linha bigquery
161
- def str_insert1
162
- ",#{row[3]},#{conta}" + str_insert2
163
- end
164
-
165
- # @return [String] campos calculados da linha bigquery
166
- def str_insert2
167
- ",#{data_valor.year},#{data_valor.month},null," \
168
- "'#{row[3].positive? ? 'c' : 'd'}')"
169
- end
170
-
171
- # @return [Integer] numero linhas apagadas
172
- def sql_delete
173
- dml('delete ' + sql_where + " and ds='#{sql.first[:ds].strip}'")
174
- end
175
- end
176
- end
@@ -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