Class: Herodot::Worklog

Inherits:
Object
  • Object
show all
Defined in:
lib/herodot/worklog.rb

Constant Summary collapse

END_TRACK_EVENTS =
%i[work_end lunch_break_start after_last_dates_end].freeze
START_TRACK_EVNETS =
%i[work_start lunch_break_end before_first_dates_start].freeze
EVENTS =
(END_TRACK_EVENTS + START_TRACK_EVNETS).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Worklog

Returns a new instance of Worklog.



8
9
10
11
12
13
# File 'lib/herodot/worklog.rb', line 8

def initialize(config)
  @raw_logs = []
  @branches = {}
  @dates = []
  @config = config
end

Instance Attribute Details

#branchesObject (readonly)

Returns the value of attribute branches.



3
4
5
# File 'lib/herodot/worklog.rb', line 3

def branches
  @branches
end

Instance Method Details

#actual_id(current_id, id) ⇒ Object



84
85
86
# File 'lib/herodot/worklog.rb', line 84

def actual_id(current_id, id)
  END_TRACK_EVENTS.include?(id) ? id : current_id || id
end

#add_entry(time, project_path, branch) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/herodot/worklog.rb', line 15

def add_entry(time, project_path, branch)
  return if project_path.nil?
  project = project_path.gsub(@config.projects_directory.to_s, '')
  id = "#{project}:#{branch}"
  @raw_logs << { time: time, id: id }
  @branches[id] = { branch: branch, project: project, path: project_path }
end

#branch(id) ⇒ Object



57
58
59
# File 'lib/herodot/worklog.rb', line 57

def branch(id)
  @branches.fetch(id, {})
end

#datesObject



61
62
63
# File 'lib/herodot/worklog.rb', line 61

def dates
  @raw_logs.map { |log| log[:time].to_date }.uniq.sort
end

#logs_with_eventsObject



23
24
25
26
27
28
29
# File 'lib/herodot/worklog.rb', line 23

def logs_with_events
  filtered_logs = @raw_logs.chunk { |x| x[:id] }.map(&:last).map(&:first)
  filtered_logs += work_time_events
  filtered_logs << { time: Time.new(0), id: :before_first_dates_start }
  filtered_logs << { time: Time.now, id: :after_last_dates_end }
  filtered_logs.sort_by { |log| log[:time] }
end

#logs_with_timesObject



31
32
33
34
35
36
37
38
39
# File 'lib/herodot/worklog.rb', line 31

def logs_with_times
  current_id = nil
  logs_with_events.each_cons(2).map do |log, following_log|
    current_id = log[:id] unless EVENTS.include?(log[:id])
    log.merge id: actual_id(current_id, log[:id]),
              time: time_between(log, following_log),
              date: log[:time].to_date
  end
end

#logs_with_times_cleanedObject



41
42
43
# File 'lib/herodot/worklog.rb', line 41

def logs_with_times_cleaned
  logs_with_times.reject { |log| EVENTS.include?(log[:id]) }
end

#same_date?(log_entry, other_log_entry) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/herodot/worklog.rb', line 75

def same_date?(log_entry, other_log_entry)
  log_entry[:time].to_date == other_log_entry[:time].to_date
end

#time_between(log_entry, following_entry) ⇒ Object



79
80
81
82
# File 'lib/herodot/worklog.rb', line 79

def time_between(log_entry, following_entry)
  return 0 unless same_date?(log_entry, following_entry)
  following_entry[:time] - log_entry[:time]
end

#totalsObject



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/herodot/worklog.rb', line 45

def totals
  grouped = logs_with_times_cleaned.group_by { |time| time[:date] }
  dates.map do |date|
    time_sums = grouped[date].each_with_object({}) do |time, sums|
      id = time[:id]
      sums[id] ||= { time: 0, **branch(id) }
      sums[id][:time] += time[:time]
    end
    [date, time_sums.values]
  end
end

#work_time_eventsObject



65
66
67
68
69
70
71
72
73
# File 'lib/herodot/worklog.rb', line 65

def work_time_events
  dates.flat_map do |date|
    @config.work_times.map { |event, (hour, minute)|
      time = Time.new(date.year, date.month, date.day, hour, minute)
      next if time > Time.now
      { id: event, time: time }
    }.compact
  end
end