timesheet 0.2.1 → 0.2.2

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.
data/Manifest.txt CHANGED
@@ -6,6 +6,7 @@ bin/timesheet
6
6
  lib/timesheet.rb
7
7
  lib/timesheet/range_extensions.rb
8
8
  lib/timesheet/time_entry.rb
9
+ lib/timesheet/report_item.rb
9
10
  lib/timesheet/time_log.rb
10
11
  lib/timesheet/time_report.rb
11
12
  lib/timesheet/timesheet_parser.rb
data/lib/timesheet.rb CHANGED
@@ -9,6 +9,7 @@ require 'yaml'
9
9
  require 'yaml/store'
10
10
  require 'timesheet/range_extensions'
11
11
  require 'timesheet/time_entry'
12
+ require 'timesheet/report_item'
12
13
  require 'timesheet/time_log'
13
14
  require 'timesheet/time_report'
14
15
  require 'timesheet/trollop'
@@ -16,7 +17,7 @@ require 'timesheet/timesheet_parser'
16
17
 
17
18
  class Timesheet
18
19
 
19
- VERSION = '0.2.1'
20
+ VERSION = '0.2.2'
20
21
 
21
22
  def self.run(params)
22
23
  command_hash = {}
@@ -0,0 +1,53 @@
1
+ require 'delegate'
2
+
3
+ class ReportItem < DelegateClass(TimeEntry)
4
+
5
+ include Comparable
6
+
7
+ def initialize( report, time_entry)
8
+ @time_entry = time_entry
9
+ super(@time_entry)
10
+ @report = report
11
+ end
12
+
13
+ def start_time
14
+ if @time_entry.to_range.include?(@report.report_start)
15
+ @report.report_start
16
+ else
17
+ @time_entry.start_time
18
+ end
19
+ end
20
+
21
+ def end_time
22
+ if to_range.include?(@report.report_end)
23
+ @report.report_end
24
+ else
25
+ @time_entry.end_time
26
+ end
27
+ end
28
+
29
+ def formatted_record_number
30
+ sprintf("%5d", @time_entry.record_number)
31
+ end
32
+
33
+ def formatted_times
34
+ puts start_time
35
+ puts end_time
36
+ str = ""
37
+ str << start_time.strftime("%m/%d/%Y at %I:%M %p")
38
+ str << " to "
39
+ str << end_time.strftime("%m/%d/%Y at ") if ((start_time.year != end_time.year) || (start_time.yday != end_time.yday))
40
+ str << end_time.strftime("%I:%M %p")
41
+ end
42
+
43
+ def formatted_duration
44
+ str = ""
45
+ str << @time_entry.duration.strftime("%d Days ") if @time_entry.duration.days > 0
46
+ str << @time_entry.duration.strftime("%hh %mm")
47
+ end
48
+
49
+ def <=>(other_time_entry)
50
+ self.start_time <=> other_time_entry.start_time
51
+ end
52
+
53
+ end
@@ -46,5 +46,19 @@ class TimeEntry
46
46
  def to_range
47
47
  Range.new(@start_time, @end_time, true)
48
48
  end
49
+
50
+ def to_s
51
+ label_width = 10
52
+ str = ""
53
+ str << "#{"class:".ljust(label_width)}#{self.class}\n"
54
+ str << "#{"record:".ljust(label_width)}#{record_number}\n"
55
+ str << "#{"project:".ljust(label_width)}#{project}\n"
56
+ str << "#{"start:".ljust(label_width)}#{start_time.strftime("%m/%d/%Y at %I:%M %p")}\n"
57
+ str << "#{"end:".ljust(label_width)}#{end_time.strftime("%m/%d/%Y at %I:%M %p")}\n"
58
+ str << "#{"duration:".ljust(label_width)}#{duration}\n"
59
+ str << "#{"comment:".ljust(label_width)}#{comment}\n"
60
+
61
+ str
62
+ end
49
63
 
50
64
  end
@@ -4,17 +4,16 @@ require 'time'
4
4
  class TimeReport
5
5
 
6
6
  def initialize(entries)
7
- @entries = entries
7
+ @entries = (entries.nil?) ? [] : entries.map { |entry| ReportItem.new(self, entry)}
8
8
  end
9
9
 
10
10
  attr_accessor :entries
11
+ attr_reader :report_start
12
+ attr_reader :report_end
11
13
 
12
- def trim(start_time, end_time)
13
- @entries.map! do |e|
14
- e.start_time = start_time if e.to_range.include?(start_time)
15
- e.end_time = end_time if e.to_range.include?(end_time)
16
- e
17
- end
14
+ def constrain(start_time, end_time)
15
+ @report_start = start_time
16
+ @report_end = end_time
18
17
  end
19
18
 
20
19
  def report(command_options, outstream = STDOUT)
@@ -22,7 +21,7 @@ class TimeReport
22
21
  if (@entries.nil? || @entries.empty?)
23
22
  outstream.puts("No data available.")
24
23
  else
25
- trim(command_options[:start], command_options[:end])
24
+ constrain(command_options[:start], command_options[:end])
26
25
 
27
26
  detail_report(outstream) if command_options[:detail]
28
27
  summary_report(outstream) if command_options[:summary]
@@ -33,29 +32,25 @@ class TimeReport
33
32
  private
34
33
 
35
34
  def detail_report(outstream)
35
+
36
+ # field_names = ["Id", "Project", "Start - Stop", "Hours", "Comment"]
37
+ # field_methods = [:formatted_record_number, :project, :formatted_times, :formatted_duration, :comment]
38
+
36
39
  table = Ruport::Data::Table({ :column_names => ["Id", "Project", "Start - Stop", "Hours", "Comment"]}) do |table|
37
40
  @entries.sort.each do |entry|
38
41
  row = []
39
42
 
40
43
  # format record number
41
- row << sprintf("%5d", entry.record_number)
44
+ row << entry.formatted_record_number
42
45
 
43
46
  # format project
44
47
  row << entry.project
45
48
 
46
49
  # format start - stop
47
- str = ""
48
- str << entry.start_time.strftime("%m/%d/%Y at %I:%M %p")
49
- str << " to "
50
- str << entry.end_time.strftime("%m/%d/%Y at ") if ( (entry.start_time.year != entry.end_time.year) && (entry.start_time.yday != entry.end_time.yday))
51
- str << entry.end_time.strftime("%I:%M %p")
52
- row << str
50
+ row << entry.formatted_times
53
51
 
54
52
  # format duration
55
- str = ""
56
- str << entry.duration.strftime("%d Days ") if entry.duration.days > 0
57
- str << entry.duration.strftime("%hh %mm")
58
- row << str
53
+ row << entry.formatted_duration
59
54
 
60
55
  # format comment
61
56
  row << entry.comment
@@ -212,7 +212,7 @@ EOS
212
212
 
213
213
  when :current_week
214
214
  periods[:start] = Chronic.parse("this week #{WEEK_START} at 12 am")
215
- periods[:end] = periods[:start] + 7.days
215
+ periods[:end] = periods[:start] + 1.week
216
216
 
217
217
  when :current_month
218
218
  today = Date.today
@@ -225,8 +225,8 @@ EOS
225
225
  periods[:end] = periods[:start] + 1.day
226
226
 
227
227
  when :last_week
228
- periods[:start] = Chronic.parse("last week #{WEEK_START} at 12 am")
229
- periods[:end] = periods[:start] + 7.days
228
+ periods[:start] = Chronic.parse("this week #{WEEK_START} at 12 am") - 1.week
229
+ periods[:end] = periods[:start] + 1.week
230
230
 
231
231
  when :last_month
232
232
  today = Date.today
@@ -17,7 +17,8 @@ describe TimeEntry do
17
17
  context "Basic Features" do
18
18
 
19
19
  before :each do
20
- @time_entry = TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 17, 0, 0))
20
+ @time_entry = TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 17, 0, 0), "a comment")
21
+ @time_entry.record_number = 1
21
22
  end
22
23
 
23
24
 
@@ -34,7 +35,8 @@ describe TimeEntry do
34
35
  end
35
36
 
36
37
  it "should have an initial comment of nil" do
37
- @time_entry.comment.should == nil
38
+ time_entry = TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 17, 0, 0))
39
+ time_entry.comment.should == nil
38
40
  end
39
41
 
40
42
  it "should calculate its duration from start and end times" do
@@ -74,6 +76,20 @@ describe TimeEntry do
74
76
  it "should not allow assignment to duration" do
75
77
  @time_entry.should_not respond_to :duration=
76
78
  end
79
+
80
+ it "should have a to_s method to display its contents" do
81
+ @time_entry.should respond_to :to_s
82
+ @time_entry.to_s.should eql( <<EOS
83
+ class: TimeEntry
84
+ record: 1
85
+ project: Project
86
+ start: 12/01/2009 at 09:00 AM
87
+ end: 12/01/2009 at 05:00 PM
88
+ duration: 0 seconds 0 minutes 8 hours 0 days
89
+ comment: a comment
90
+ EOS
91
+ )
92
+ end
77
93
 
78
94
  end
79
95
 
@@ -13,13 +13,13 @@ describe TimeReport do
13
13
  end
14
14
 
15
15
  it "should be able to trim its entries to a specific time span" do
16
- @time_report.trim(Time.local(2009, 12, 1, 11, 0, 0), Time.local(2009, 12, 5, 12, 0, 0))
16
+ @time_report.constrain(Time.local(2009, 12, 1, 11, 0, 0), Time.local(2009, 12, 5, 12, 0, 0))
17
17
  @time_report.entries[0].start_time.should eql(Time.local(2009, 12, 1, 11, 0, 0))
18
18
  @time_report.entries[-1].end_time.should eql(Time.local(2009, 12, 5, 12, 0, 0))
19
19
  end
20
20
 
21
21
  it "should leave entries alone when the trim span is outside the entry range" do
22
- @time_report.trim(Time.local(2009, 11, 1, 0, 0, 0), Time.local(2009, 12, 31, 0, 0, 0))
22
+ @time_report.constrain(Time.local(2009, 11, 1, 0, 0, 0), Time.local(2009, 12, 31, 0, 0, 0))
23
23
  @time_report.entries[0].start_time.should eql(Time.local(2009, 12, 1, 9, 0, 0))
24
24
  @time_report.entries[-1].end_time.should eql(Time.local(2009, 12, 5, 17, 0, 0))
25
25
  end
@@ -92,6 +92,7 @@ EOS
92
92
 
93
93
  it "should be able to produce a byday report" do
94
94
  @entries << TimeEntry.new("ProjectB", Time.local(2009, 12, 1, 17, 0, 0), Time.local(2009, 12, 1, 19, 0, 0), "another comment")
95
+ @time_report = TimeReport.new(@entries)
95
96
 
96
97
  command_options = {:byday => true, :start => Time.local(2009, 12, 1), :end => Time.local(2009, 12, 6)}
97
98
  stream = StringIO.new
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timesheet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John F. Schank III
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-11 00:00:00 -05:00
12
+ date: 2010-02-07 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -225,6 +225,7 @@ files:
225
225
  - lib/timesheet.rb
226
226
  - lib/timesheet/range_extensions.rb
227
227
  - lib/timesheet/time_entry.rb
228
+ - lib/timesheet/report_item.rb
228
229
  - lib/timesheet/time_log.rb
229
230
  - lib/timesheet/time_report.rb
230
231
  - lib/timesheet/timesheet_parser.rb