abank 0.2.3 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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