twstats 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/lib/twstats.rb +2 -0
- data/lib/twstats/csv_reader.rb +2 -9
- data/lib/twstats/descriptive_stats.rb +23 -0
- data/lib/twstats/runner.rb +19 -7
- data/lib/twstats/timesheet_export.rb +1 -1
- data/lib/twstats/tw_log.rb +3 -1
- data/twstats.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0589a754ec65039304f94cd58dc6339829ee2485bf7a2e782de8ca3e9186ba9a'
|
4
|
+
data.tar.gz: 689f96336353325219a3ed14317e3de8206de93dc975e230afd7feebf0a844aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1a24c4cffc2df2f36ecaabbe5873966664dd94f40be6dbfba5d2f9a8de04876a139edc0ac6912a65de4b0a38102b26dceb2ebbe2ec5e1b72c407c786410f218
|
7
|
+
data.tar.gz: 3c09c2ead64c69a666f1da1c7ae2d2ea6971c1c3c45ebc2509aa026cfb237f601d9cd2592b61df53ec845f2e7bbc7ae36573787895ba8aa6fba2c7141d95fae3
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
twstats (0.2.
|
4
|
+
twstats (0.2.4.pre.6.pre.g29c9d57)
|
5
|
+
descriptive-statistics (>= 2.2.0)
|
5
6
|
rainbow (~> 3.0)
|
6
7
|
tty-prompt (~> 0.17)
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: https://rubygems.org/
|
10
11
|
specs:
|
12
|
+
descriptive-statistics (2.2.0)
|
11
13
|
diff-lcs (1.3)
|
12
14
|
equatable (0.5.0)
|
13
15
|
hitimes (1.3.0)
|
data/lib/twstats.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative 'twstats/extensions'
|
|
2
2
|
require_relative 'twstats/version'
|
3
3
|
require_relative 'twstats/tw_log'
|
4
4
|
require_relative 'twstats/csv_reader'
|
5
|
+
require_relative 'twstats/descriptive_stats'
|
5
6
|
require_relative 'twstats/timesheet_export'
|
6
7
|
require_relative 'twstats/runner'
|
7
8
|
|
@@ -14,6 +15,7 @@ module Twstats
|
|
14
15
|
{name: 'Projects', value: :projects},
|
15
16
|
{name: 'People', value: :people},
|
16
17
|
{name: 'Tags', value: :tags},
|
18
|
+
{name: 'Tasks', value: :tasks},
|
17
19
|
{name: 'Full stats', value: :fullstats},
|
18
20
|
{name: 'Weekly', value: :weekly},
|
19
21
|
{name: 'Back', value: :back}
|
data/lib/twstats/csv_reader.rb
CHANGED
@@ -32,14 +32,6 @@ module Twstats
|
|
32
32
|
logs.inject(0) {|sum, log| sum + log.decimal_time }.to_f/logs.size
|
33
33
|
end
|
34
34
|
|
35
|
-
def mean_time_per_task
|
36
|
-
time_per_task = []
|
37
|
-
tasks.each do |task|
|
38
|
-
time_per_task << logs.select{|ll| ll.task == task}.inject(0){|sum, ll| sum + ll.decimal_time}
|
39
|
-
end
|
40
|
-
time_per_task.inject(0){|sum, x| sum + x}/time_per_task.size
|
41
|
-
end
|
42
|
-
|
43
35
|
def get_total_time(object, element, filter_billable)
|
44
36
|
billable = 0
|
45
37
|
non_billable = 0
|
@@ -62,8 +54,9 @@ module Twstats
|
|
62
54
|
else
|
63
55
|
return -99999
|
64
56
|
end
|
57
|
+
puts "bill: #{billable}, nonbill: #{non_billable}"
|
65
58
|
if filter_billable
|
66
|
-
return billable, non_billable
|
59
|
+
return [billable, non_billable]
|
67
60
|
else
|
68
61
|
return billable + non_billable
|
69
62
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'descriptive-statistics' # Small gem with descriptive statistics functionalities
|
2
|
+
module Twstats
|
3
|
+
class LogStats
|
4
|
+
attr_reader :logs
|
5
|
+
# This class analyzes a give set of data and is used to extract information from times logged
|
6
|
+
def initialize(logs)
|
7
|
+
@logs = logs
|
8
|
+
end
|
9
|
+
|
10
|
+
def mean_log_time
|
11
|
+
map = logs.map{|l| l.decimal_time}
|
12
|
+
DescriptiveStatistics::Stats.new(map).mean
|
13
|
+
end
|
14
|
+
|
15
|
+
def mean_task_time(tasks)
|
16
|
+
time_per_task = []
|
17
|
+
tasks.each do |task|
|
18
|
+
time_per_task << logs.select{|ll| ll.task == task}.inject(0){|sum, ll| sum + ll.decimal_time}
|
19
|
+
end
|
20
|
+
DescriptiveStatistics::Stats.new(time_per_task).mean
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/twstats/runner.rb
CHANGED
@@ -40,7 +40,7 @@ module Twstats
|
|
40
40
|
loop do
|
41
41
|
option = @prompt.select("Select what time logging stats you want to see", Twstats::STATS_MENU_CHOICES, cycle: true)
|
42
42
|
case option
|
43
|
-
when :projects, :people, :tags
|
43
|
+
when :projects, :people, :tags, :tasks
|
44
44
|
show_stats option
|
45
45
|
when :fullstats
|
46
46
|
show_full_stats
|
@@ -114,12 +114,24 @@ module Twstats
|
|
114
114
|
to_bill = @prompt.yes? 'Do you want to calculate the billed amount?'
|
115
115
|
if to_bill
|
116
116
|
amount_per_hour = @prompt.ask 'What is the hourly rate?', default: 46
|
117
|
+
if @prompt.yes? 'Was it a closed quote?', default: true
|
118
|
+
quoted_price = @prompt.ask 'What was the quoted price for this project?', convert: :float
|
119
|
+
end
|
117
120
|
end
|
118
121
|
section "Total time spent"
|
119
122
|
puts " - Billable ".bright.blue + " | " + billable.round(2).to_s
|
120
123
|
puts " - Non-billable ".bright.blue + " | " + non_billable.round(2).to_s
|
121
124
|
if to_bill
|
122
|
-
|
125
|
+
price = billable*amount_per_hour
|
126
|
+
puts " - Billed amount ".bright.blue + " | " + price.round(2).to_s + " € "
|
127
|
+
if quoted_price
|
128
|
+
diff = quoted_price-price
|
129
|
+
if diff >= 0
|
130
|
+
puts " - Project over estimated: #{diff.round(2)} €, #{diff/price}".bright.green
|
131
|
+
else diff < 0
|
132
|
+
puts " - Project under estimated: #{diff.round(2)} €, #{(diff*100/price).round(2)}%".bright.red
|
133
|
+
end
|
134
|
+
end
|
123
135
|
end
|
124
136
|
section "People involved"
|
125
137
|
show_stats :people, true
|
@@ -149,14 +161,14 @@ module Twstats
|
|
149
161
|
|
150
162
|
def section(text)
|
151
163
|
puts ""
|
152
|
-
puts (" "+text+" ").center(70,"*").bright
|
164
|
+
puts (" "+text+" ").center(70,"*").bright.orange
|
153
165
|
end
|
154
166
|
|
155
167
|
def show_metrics
|
156
|
-
|
157
|
-
|
158
|
-
puts " - Mean time
|
159
|
-
puts "
|
168
|
+
stats = LogStats.new(@csv.logs)
|
169
|
+
puts " - Mean time logged: ".bright.blue + stats.mean_log_time.round(2).to_s
|
170
|
+
puts " - Mean time per task: ".bright.blue + stats.mean_task_time(@csv.tasks).round(2).to_s
|
171
|
+
puts " - With a total of #{@csv.tasks.size} tasks"
|
160
172
|
end
|
161
173
|
|
162
174
|
def show_weekly_report
|
@@ -7,7 +7,7 @@ module Twstats
|
|
7
7
|
@prompt = prompt
|
8
8
|
@rows = []
|
9
9
|
# Filter by billable and not billed
|
10
|
-
csv.logs.select{|x| x.billable && !x.invoiced}.sort_by{|x| x.
|
10
|
+
csv.logs.select{|x| x.billable && !x.invoiced}.sort_by{|x| x.start_date}.each do |log|
|
11
11
|
@rows << {
|
12
12
|
date: log.date.strftime('%m/%d/%Y'),
|
13
13
|
who: public_name(log.who),
|
data/lib/twstats/tw_log.rb
CHANGED
@@ -11,6 +11,7 @@ module Twstats
|
|
11
11
|
attr_reader :task
|
12
12
|
attr_reader :billable
|
13
13
|
attr_reader :invoiced
|
14
|
+
attr_reader :start_date
|
14
15
|
|
15
16
|
# Class use to store the information needed form a given log
|
16
17
|
def initialize(row)
|
@@ -19,12 +20,13 @@ module Twstats
|
|
19
20
|
@decimal_time = row["Decimal Hours"].to_f
|
20
21
|
@time = (DateTime.parse(row["End Date/Time"]) - DateTime.parse(row["Date/Time"]))*24
|
21
22
|
@description = row["Description"]
|
22
|
-
@tags = row['Tags'].nil? ? [] : row["Tags"].split(',')
|
23
|
+
@tags = row['Tags'].nil? ? [] : row["Tags"].split(',').map{|x| x.strip}
|
23
24
|
@project = row["Project"]
|
24
25
|
@task = row["Task"]
|
25
26
|
@billable = !row["Is it Billable?"].to_i.zero?
|
26
27
|
@invoiced = !row['Invoice Number']
|
27
28
|
@date = DateTime.parse(row['Date'])
|
29
|
+
@start_date = DateTime.parse(row["Date/Time"])
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
data/twstats.gemspec
CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_development_dependency "rspec", "~> 3.0"
|
38
38
|
spec.add_runtime_dependency "tty-prompt", "~> 0.17"
|
39
39
|
spec.add_runtime_dependency "rainbow", "~> 3.0"
|
40
|
+
spec.add_runtime_dependency "descriptive-statistics", ">=2.2.0"
|
40
41
|
|
41
42
|
spec.required_ruby_version = '~> 2.1'
|
42
43
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twstats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- J.P. Araque
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: descriptive-statistics
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.2.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.2.0
|
83
97
|
description: Teamwork allows to log time for all tasks within a project but the stats
|
84
98
|
capabilities do not allow for a quick overview of time loggin stats. TWStats produces
|
85
99
|
useful stats from a CSV file exported from Teamwork
|
@@ -104,6 +118,7 @@ files:
|
|
104
118
|
- exe/twstats
|
105
119
|
- lib/twstats.rb
|
106
120
|
- lib/twstats/csv_reader.rb
|
121
|
+
- lib/twstats/descriptive_stats.rb
|
107
122
|
- lib/twstats/extensions.rb
|
108
123
|
- lib/twstats/runner.rb
|
109
124
|
- lib/twstats/timesheet_export.rb
|