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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f34d4ba10054132e2b0cddb54033e418979735a7ea7c5e3d487f40eb2c5472e7
4
- data.tar.gz: 1017e1b74d4cf8da667b634ea71285952f9f9c44a7b297cb2c8c31c21f884406
3
+ metadata.gz: '0589a754ec65039304f94cd58dc6339829ee2485bf7a2e782de8ca3e9186ba9a'
4
+ data.tar.gz: 689f96336353325219a3ed14317e3de8206de93dc975e230afd7feebf0a844aa
5
5
  SHA512:
6
- metadata.gz: 21bff3055a10fd3fafb6d92647a2537afb908024e053e7bfca171532e4e7ad55e3eb7758656e8a35895411b520184d526f07b631e1ad9989d1f53855ed257182
7
- data.tar.gz: 128b0efb50ae73c9b7b598b841ebdfeb66fb38b4ce510d2fe2a8e1b1f290cd23bfccddabb37dc4bd8fa8bee495b7fda6b0f8cd5e377b142a395aaf644170763a
6
+ metadata.gz: b1a24c4cffc2df2f36ecaabbe5873966664dd94f40be6dbfba5d2f9a8de04876a139edc0ac6912a65de4b0a38102b26dceb2ebbe2ec5e1b72c407c786410f218
7
+ data.tar.gz: 3c09c2ead64c69a666f1da1c7ae2d2ea6971c1c3c45ebc2509aa026cfb237f601d9cd2592b61df53ec845f2e7bbc7ae36573787895ba8aa6fba2c7141d95fae3
@@ -1,13 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twstats (0.2.3.pre.2.pre.g8db668b)
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)
@@ -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}
@@ -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
@@ -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
- puts " - Billed amount ".bright.blue + " | " + (billable*amount_per_hour).round(2).to_s + " € "
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
- mean = @csv.logs.inject(0) {|sum, log| sum + log.decimal_time }.to_f/@csv.logs.size
157
- mean_per_task = @csv.mean_time_per_task
158
- puts " - Mean time logged: ".bright.blue + mean.round(2).to_s
159
- puts " - Mean time per task: ".bright.blue + mean_per_task.round(2).to_s
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.date}.each do |log|
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),
@@ -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
@@ -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
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-03 00:00:00.000000000 Z
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