avmtrf1-tools 0.11.2 → 0.12.0

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: 4d9d2aeb4f8c6609917bfee3a3b9e8991ae24a7e10adaacdb87f04e4409a68e3
4
- data.tar.gz: 703ccfa1ee139154efa028805063f7b9477a89842d5f1ecc963e450b6e2a0d52
3
+ metadata.gz: ef001c26f83ae5f6ca0752cad6eac0eeff0cc402cfe6f5f2acf27ced7e36e2ee
4
+ data.tar.gz: c5f0fb9404e584124a954498d8eb4db22dad6b0b4b383e664e6a3e0d538fef55
5
5
  SHA512:
6
- metadata.gz: db0460a5171348b0d4aa85553e6c25e99bf7c2430e942874a179b034b2324192a0411533cbdf08a53b7f5136667eb630f5a41dc491c5e9fb2ca83f385839f493
7
- data.tar.gz: 6d728ac9aaff3309cd57abed5d8e99241c3054a3c08df6a45ae8bd92aeff7733fabfd65e8372f1b9162f4ff057f805002311d7a0abacd7fbbf8857efa19ea27f
6
+ metadata.gz: 8eeb23824123920f62d4b6030ad7b1833fda4e0585e444e2730968565ff784cc091581922ae689cc155f8f47f07b636e633335db3117d09e1d42d22a076bf48e
7
+ data.tar.gz: f7b141e875ff41297f2b5e2921bd34b92da87e2834e049fd2d9e246df72d9ac09d700626ca3ec46bfaf696f357fe70345c7636924e59510fb538ec0eba08da67
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avmtrf1
4
+ module Forponto
5
+ class User
6
+ class Balance
7
+ include ::EacRubyUtils::SimpleCache
8
+
9
+ attr_reader :user
10
+
11
+ def initialize(user)
12
+ @user = user
13
+ build_balances
14
+ end
15
+
16
+ def months_balances_uncached
17
+ sorted_months.map { |m| MyBalance.new(m) }
18
+ end
19
+
20
+ def sorted_months_uncached
21
+ r = []
22
+ current = head_month
23
+ while current.present?
24
+ r << current
25
+ current = current.parent_month
26
+ end
27
+ r.reverse
28
+ end
29
+
30
+ def head_month
31
+ today = ::Date.today
32
+ date = ::Date.civil(today.year, today.month, 1)
33
+ user.month(date.year, date.month)
34
+ end
35
+
36
+ def debito_left
37
+ months_balances.inject(0) { |a, e| a + e.debito.left }
38
+ end
39
+
40
+ def credito_left
41
+ months_balances.inject(0) { |a, e| a + e.credito.left }
42
+ end
43
+
44
+ def saldo_left
45
+ credito_left - debito_left
46
+ end
47
+
48
+ private
49
+
50
+ def build_balances
51
+ previous = []
52
+ months_balances.each do |current|
53
+ current.consume(previous)
54
+ previous << current
55
+ if previous.count > 3
56
+ removed = previous.shift
57
+ removed.mark_lost
58
+ end
59
+ end
60
+ end
61
+
62
+ class MyBalance
63
+ attr_accessor :debito, :credito, :month, :lost
64
+
65
+ def initialize(month)
66
+ @month = month
67
+ @debito = AttrConsumer.new(self, false, month.debito)
68
+ @credito = AttrConsumer.new(self, true, month.credito)
69
+ @lost = false
70
+ end
71
+
72
+ def after_trigger
73
+ credito.after_trigger - debito.after_trigger
74
+ end
75
+
76
+ def after_trigger_acum
77
+ credito.after_trigger_acum - debito.after_trigger_acum
78
+ end
79
+
80
+ def mark_lost
81
+ @lost = true
82
+ end
83
+
84
+ def to_s
85
+ month.to_s
86
+ end
87
+
88
+ def consume(previous)
89
+ debito.consume_from_months(previous)
90
+ credito.consume_from_months(previous)
91
+ end
92
+
93
+ class AttrConsumer
94
+ attr_reader :owner_month, :initial_value, :left, :unconsumed, :withdrawals, :requests,
95
+ :after_trigger, :after_trigger_acum
96
+
97
+ def initialize(owner_month, credito, initial_value)
98
+ @owner_month = owner_month
99
+ @credito = credito
100
+ @left = initial_value
101
+ @initial_value = initial_value
102
+ @withdrawals = []
103
+ @requests = []
104
+ @after_trigger = nil
105
+ end
106
+
107
+ def to_s
108
+ "[#{owner_month}|#{attr}]"
109
+ end
110
+
111
+ def consume_from_months(months)
112
+ (months + [owner_month]).each do |month|
113
+ break unless left.positive?
114
+
115
+ consume_from_month(month)
116
+ end
117
+ @after_trigger = left
118
+ @after_trigger_acum = months.inject(0) { |a, e| a + e.send(attr).left } + left
119
+ end
120
+
121
+ def withdrawal(month, value)
122
+ month.assert_argument(MyBalance, :month)
123
+ raise "Value is not positive: #{value} (Month: #{month})" unless value.positive?
124
+
125
+ self.left -= value
126
+ raise "Left less than zero: #{left} (Value: #{value})" if left.negative?
127
+
128
+ @withdrawals << OpenStruct.new(month: month, value: value)
129
+ end
130
+
131
+ private
132
+
133
+ attr_writer :left, :unconsumed
134
+
135
+ def consume_from_month(month)
136
+ month_attr = month.send(reverse_attr)
137
+ return unless month_attr.left.positive?
138
+
139
+ value = [left, month_attr.left].min
140
+ self.left -= value
141
+ month_attr.withdrawal(owner_month, value)
142
+ @requests << OpenStruct.new(month: month, value: value)
143
+ end
144
+
145
+ def attr
146
+ @credito ? :credito : :debito
147
+ end
148
+
149
+ def reverse_attr
150
+ @credito ? :debito : :credito
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -3,6 +3,7 @@
3
3
  require 'active_support/json'
4
4
  require 'eac_ruby_utils/core_ext'
5
5
  require 'eac_ruby_utils/yaml'
6
+ require 'recursive-open-struct'
6
7
  require 'avmtrf1/forponto/parsers/espelho'
7
8
  require 'avmtrf1/forponto/session'
8
9
  require 'avmtrf1/fs_cache'
@@ -30,7 +31,7 @@ module Avmtrf1
30
31
  data_cache.write(r.to_yaml)
31
32
  r
32
33
  else
33
- ::EacRubyUtils::Yaml.load_common(data_cache.read)
34
+ cached_data
34
35
  end
35
36
  end
36
37
 
@@ -86,11 +87,19 @@ module Avmtrf1
86
87
  end
87
88
 
88
89
  def recache?
89
- !data_cache.cached?
90
+ !data_cache.cached? || yesterday_uncached?
91
+ end
92
+
93
+ def yesterday_uncached?
94
+ last_cached_day < end_date && last_cached_day < (::Date.today - 1.days)
95
+ end
96
+
97
+ def last_cached_day_uncached
98
+ cached_data.fetch('days').map { |day| day.fetch('date') }.max
90
99
  end
91
100
 
92
101
  def data_cache_uncached
93
- ::Avmtrf1.fs_cache.child('forponto', user.matricula, month.to_s.rjust(2, '0'))
102
+ ::Avmtrf1.fs_cache.child('forponto', user.matricula, year.to_s, month.to_s.rjust(2, '0'))
94
103
  end
95
104
 
96
105
  def date(day)
@@ -105,6 +114,12 @@ module Avmtrf1
105
114
  date(-1)
106
115
  end
107
116
 
117
+ def cached_data
118
+ raise 'There is no data cached' unless data_cache.cached?
119
+
120
+ ::EacRubyUtils::Yaml.load_common(data_cache.read)
121
+ end
122
+
108
123
  def fresh_data
109
124
  session = new_session
110
125
  begin
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'avm/templates/directory'
4
- require 'avm/templates/file'
3
+ require 'eac_ruby_utils/templates/searcher'
5
4
 
6
5
  module Avmtrf1
7
6
  class << self
@@ -9,12 +8,16 @@ module Avmtrf1
9
8
  ::File.expand_path('../../template', __dir__)
10
9
  end
11
10
 
12
- def template(subpath)
13
- path = ::File.join(templates_root, subpath)
14
- return ::Avm::Templates::Directory.new(path) if ::File.directory?(path)
15
- return ::Avm::Templates::File.new(path) if ::File.file?(path)
11
+ def template_searcher
12
+ @template_searcher ||= begin
13
+ r = ::EacRubyUtils::Templates::Searcher.new
14
+ r.included_paths << templates_root
15
+ r
16
+ end
17
+ end
16
18
 
17
- raise "Template \"#{path}\" not found"
19
+ def template(subpath)
20
+ template_searcher.template(subpath)
18
21
  end
19
22
  end
20
23
  end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avmtrf1
4
+ module Tools
5
+ class Runner < ::EacRubyUtils::Console::DocoptRunner
6
+ class Forponto < ::EacRubyUtils::Console::DocoptRunner
7
+ class Resumos < ::EacRubyUtils::Console::DocoptRunner
8
+ include ::EacRubyUtils::SimpleCache
9
+ include ::EacRubyUtils::Console::Speaker
10
+
11
+ DOC = <<~DOCOPT
12
+ Mostra os resumos.
13
+
14
+ Usage:
15
+ __PROGRAM__ [options]
16
+ __PROGRAM__ -h | --help
17
+
18
+ Options:
19
+ -h --help Show this screen.
20
+ DOCOPT
21
+
22
+ def run
23
+ sorted_months.each do |month|
24
+ show_month(month)
25
+ end
26
+ end
27
+
28
+ def head_month
29
+ today = ::Date.today
30
+ date = ::Date.civil(today.year, today.month, 1)
31
+ context(:user).month(date.year, date.month)
32
+ end
33
+
34
+ def show_month(month)
35
+ infov 'Month', month
36
+ show_self_summaries(month)
37
+ end
38
+
39
+ def show_self_summaries(month)
40
+ infov ' * Self summaries', month.os_data.summaries.count
41
+ show_month_summaries(month)
42
+ show_month_self_summaries(month)
43
+ show_month_acum_summaries(month)
44
+ end
45
+
46
+ def show_month_summaries(month)
47
+ month.os_data.summaries.each do |s|
48
+ infov ' * ' + summary_to_label(s), summary_to_value(s)
49
+ end
50
+ end
51
+
52
+ def show_month_self_summaries(month)
53
+ infov ' * Débito', minutes_to_s(month.debito)
54
+ infov ' * Crédito', minutes_to_s(month.credito)
55
+ infov ' * Saldo', minutes_to_s(month.saldo)
56
+ end
57
+
58
+ def show_month_acum_summaries(month)
59
+ infov ' * Débito acum.', minutes_to_s(month.debito_acum)
60
+ infov ' * Crédito acum.', minutes_to_s(month.credito_acum)
61
+ infov ' * Saldo acum.', minutes_to_s(month.saldo_acum)
62
+ end
63
+
64
+ def summary_to_label(summary)
65
+ "#{summary.code} - #{summary.description}"
66
+ end
67
+
68
+ def summary_to_value(summary)
69
+ minutes_to_s(summary.minutes)
70
+ end
71
+
72
+ def minutes_to_s(minutes)
73
+ signal = ''
74
+ if minutes.negative?
75
+ signal = '-'
76
+ minutes = -minutes
77
+ end
78
+ time = [minutes / 60, minutes % 60].map { |x| x.to_s.rjust(2, '0') }.join(':')
79
+ "#{signal}#{time} / #{signal}#{minutes} minutes"
80
+ end
81
+
82
+ def sorted_months_uncached
83
+ r = []
84
+ current = head_month
85
+ while current.present?
86
+ r << current
87
+ current = current.parent_month
88
+ end
89
+ r.reverse
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avmtrf1
4
+ module Tools
5
+ class Runner < ::EacRubyUtils::Console::DocoptRunner
6
+ class Forponto < ::EacRubyUtils::Console::DocoptRunner
7
+ class Saldo < ::EacRubyUtils::Console::DocoptRunner
8
+ include ::EacRubyUtils::SimpleCache
9
+ include ::EacRubyUtils::Console::Speaker
10
+
11
+ DOC = <<~DOCOPT
12
+ Calcula saldo de horas atual.
13
+
14
+ Usage:
15
+ __PROGRAM__ [options]
16
+ __PROGRAM__ -h | --help
17
+
18
+ Options:
19
+ -h --help Show this screen.
20
+ -d --details Show details.
21
+ DOCOPT
22
+
23
+ def run
24
+ balance.months_balances.each do |mb|
25
+ show_balance_month(mb)
26
+ end
27
+ end_banner
28
+ end
29
+
30
+ def end_banner
31
+ infov 'Crédito final', minutes_to_s(balance.credito_left)
32
+ infov 'Débito final', minutes_to_s(balance.debito_left)
33
+ infov 'Saldo final', minutes_to_s(balance.saldo_left)
34
+ end
35
+
36
+ def show_balance_month(balance_month)
37
+ infov 'Month', balance_month.month
38
+ show_month_attr_balance(balance_month.credito, 'Crédito')
39
+ show_month_attr_balance(balance_month.debito, 'Débito')
40
+ infov ' * After trigger', minutes_to_s(balance_month.after_trigger)
41
+ infov ' * After trigger acum.', minutes_to_s(balance_month.after_trigger_acum)
42
+ end
43
+
44
+ def show_month_attr_balance(mba, label)
45
+ infov " * #{label}", minutes_to_s(mba.initial_value)
46
+ return unless options.fetch('--details')
47
+
48
+ show_month_withdrawals(mba)
49
+ show_month_requests(mba)
50
+ show_month_end_resume(mba)
51
+ end
52
+
53
+ def show_month_withdrawals(mba)
54
+ infov ' * Withdrawals', mba.withdrawals.count
55
+ mba.withdrawals.each do |w|
56
+ infov " * #{w.month.month}", minutes_to_s(w.value)
57
+ end
58
+ end
59
+
60
+ def show_month_requests(mba)
61
+ infov ' * Requests', mba.requests.count
62
+ mba.requests.each do |r|
63
+ infov " * #{r.month.month}", minutes_to_s(r.value)
64
+ end
65
+ end
66
+
67
+ def show_month_end_resume(mba)
68
+ infov ' * Left', minutes_to_s(mba.left) + ' ' + left_status(mba)
69
+ infov ' * After trigger', minutes_to_s(mba.after_trigger)
70
+ infov ' * After trigger acum.', minutes_to_s(mba.after_trigger_acum)
71
+ end
72
+
73
+ def left_status(mba)
74
+ if mba.left.positive? && mba.owner_month.lost
75
+ '[LOST]'.red
76
+ else
77
+ '[OK]'
78
+ end
79
+ end
80
+
81
+ def minutes_to_s(minutes)
82
+ signal = ''
83
+ if minutes.negative?
84
+ signal = '-'
85
+ minutes = -minutes
86
+ end
87
+ time = [minutes / 60, minutes % 60].map { |x| x.to_s.rjust(2, '0') }.join(':')
88
+ "#{signal}#{time} / #{signal}#{minutes} minutes"
89
+ end
90
+
91
+ def balance_uncached
92
+ ::Avmtrf1::Forponto::User::Balance.new(context(:user))
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Avmtrf1
4
4
  module Tools
5
- VERSION = '0.11.2'
5
+ VERSION = '0.12.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avmtrf1-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo H. Bogoni
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-25 00:00:00.000000000 Z
11
+ date: 2019-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aranha-parsers
@@ -154,6 +154,20 @@ dependencies:
154
154
  - - ">="
155
155
  - !ruby/object:Gem::Version
156
156
  version: '0'
157
+ - !ruby/object:Gem::Dependency
158
+ name: recursive-open-struct
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: '1.1'
164
+ type: :runtime
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - "~>"
169
+ - !ruby/object:Gem::Version
170
+ version: '1.1'
157
171
  - !ruby/object:Gem::Dependency
158
172
  name: rspec
159
173
  requirement: !ruby/object:Gem::Requirement
@@ -254,6 +268,7 @@ files:
254
268
  - lib/avmtrf1/forponto/parsers/espelho/utils.rb
255
269
  - lib/avmtrf1/forponto/session.rb
256
270
  - lib/avmtrf1/forponto/user.rb
271
+ - lib/avmtrf1/forponto/user/balance.rb
257
272
  - lib/avmtrf1/forponto/user/month.rb
258
273
  - lib/avmtrf1/fs_cache.rb
259
274
  - lib/avmtrf1/git.rb
@@ -313,6 +328,8 @@ files:
313
328
  - lib/avmtrf1/tools/runner/esosti.rb
314
329
  - lib/avmtrf1/tools/runner/forponto.rb
315
330
  - lib/avmtrf1/tools/runner/forponto/espelho.rb
331
+ - lib/avmtrf1/tools/runner/forponto/resumos.rb
332
+ - lib/avmtrf1/tools/runner/forponto/saldo.rb
316
333
  - lib/avmtrf1/tools/runner/git.rb
317
334
  - lib/avmtrf1/tools/runner/git/issues_check.rb
318
335
  - lib/avmtrf1/tools/runner/git/push_large.rb