Class: TimeSheet::Time::Entry

Inherits:
Object
  • Object
show all
Defined in:
lib/time_sheet/time/entry.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Entry

Returns a new instance of Entry.



6
7
8
# File 'lib/time_sheet/time/entry.rb', line 6

def initialize(data)
  @data = data
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



10
11
12
# File 'lib/time_sheet/time/entry.rb', line 10

def data
  @data
end

#exceptionObject

Returns the value of attribute exception.



10
11
12
# File 'lib/time_sheet/time/entry.rb', line 10

def exception
  @exception
end

#nextObject

Returns the value of attribute next.



10
11
12
# File 'lib/time_sheet/time/entry.rb', line 10

def next
  @next
end

#prevObject

Returns the value of attribute prev.



10
11
12
# File 'lib/time_sheet/time/entry.rb', line 10

def prev
  @prev
end

Class Method Details

.attrib_matches_any?(value, patterns) ⇒ Boolean

Returns:

  • (Boolean)


219
220
221
222
223
224
225
# File 'lib/time_sheet/time/entry.rb', line 219

def self.attrib_matches_any?(value, patterns)
  return true if !patterns

  patterns.split(/\s*,\s*/).any? do |pattern|
    value.match(pattern)
  end
end

.nowObject



2
3
4
# File 'lib/time_sheet/time/entry.rb', line 2

def self.now
  @now ||= Time.now
end

.parse_tags(string) ⇒ Object



227
228
229
# File 'lib/time_sheet/time/entry.rb', line 227

def self.parse_tags(string)
  (string || '').to_s.downcase.split(/\s*,\s*/).map{|t| t.strip}
end

Instance Method Details

#<=>(other) ⇒ Object



215
216
217
# File 'lib/time_sheet/time/entry.rb', line 215

def <=>(other)
  (self.date <=> other.date) || self.start <=> other.start
end

#activityObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/time_sheet/time/entry.rb', line 16

def activity
  if !@data['activity']
    carry_mode = TimeSheet.options[:carry_over_activity]
    use_prev = (
      carry_mode == 'previous' ||
      (carry_mode == 'same-description' && self.prev.description == description)
    )
    if use_prev
      @data['activity'] = self.prev.activity
    end

    @data['activity'] ||= TimeSheet.options[:default_activity] || ''
  end

  @data['activity']
end

#dateObject



37
38
39
# File 'lib/time_sheet/time/entry.rb', line 37

def date
  @date ||= @data['date'] || self.prev.date
end

#descriptionObject



33
34
35
# File 'lib/time_sheet/time/entry.rb', line 33

def description
  @data['description'] ||= self.prev.description
end

#durationObject

def end_zone

@end_zone ||= if v = @data['end_zone']
  # allow a name prefixing the value
  v.split(/\s/).last
elsif self.prev && v = self.prev.end_zone
  v
else
  # self.class.now.getlocal.utc_offset
  # use this process' timezone
  nil
end

end



111
112
113
# File 'lib/time_sheet/time/entry.rb', line 111

def duration
  (self.end - self.start) / 60
end

#employeeObject



79
80
81
# File 'lib/time_sheet/time/entry.rb', line 79

def employee
  @employee ||= @data['employee'] || (self.prev ? self.prev.employee : 'Me')
end

#endObject



49
50
51
52
53
54
55
56
57
# File 'lib/time_sheet/time/entry.rb', line 49

def end
  ends_at = @data['end'] || (self.next ? self.next.start : self.class.now)

  @end ||= Time.mktime(
    date.year, date.month, date.day,
    hour_for(ends_at),
    minute_for(ends_at)
  )
end

#has_tags?(tags) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/time_sheet/time/entry.rb', line 139

def has_tags?(tags)
  return true if tags.empty?

  tags.all? do |tag|
    if tag.match?(/^\!/)
      t = tag.gsub(/\!/, '')
      !self.tags.include?(t)
    else
      self.tags.include?(tag)
    end
  end
end

#hour_for(timish) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/time_sheet/time/entry.rb', line 59

def hour_for(timish)
  case timish
  when Time then timish.hour
  when DateTime then timish.hour
  when Integer then timish / 60 / 60
  else
    binding.pry
  end
end

#matches?(filters) ⇒ Boolean

Returns:

  • (Boolean)


123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/time_sheet/time/entry.rb', line 123

def matches?(filters)
  from = (filters[:from] ? filters[:from] : nil)
  from = from.to_time if from.is_a?(Date)
  to = (filters[:to] ? filters[:to] : nil)
  to = (to + 1).to_time if to.is_a?(Date)
  tags = self.class.parse_tags(filters[:tags])

  has_tags?(tags) &&
  self.class.attrib_matches_any?(employee, filters[:employee]) &&
  self.class.attrib_matches_any?(description, filters[:description]) &&
  self.class.attrib_matches_any?(project, filters[:project]) &&
  self.class.attrib_matches_any?(activity, filters[:activity]) &&
  (!from || from <= self.start) &&
  (!to || to >= self.end)
end

#minute_for(timish) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/time_sheet/time/entry.rb', line 69

def minute_for(timish)
  case timish
  when Time then timish.min
  when DateTime then timish.min
  when Integer then timish / 60 % 60
  else
    binding.pry
  end
end

#projectObject



12
13
14
# File 'lib/time_sheet/time/entry.rb', line 12

def project
  @data['project'] ||= self.prev.project
end

#startObject



41
42
43
44
45
46
47
# File 'lib/time_sheet/time/entry.rb', line 41

def start
  @start ||= Time.mktime(
    date.year, date.month, date.day,
    hour_for(@data['start']),
    minute_for(@data['start'])
  )
end

#tagsObject



115
116
117
# File 'lib/time_sheet/time/entry.rb', line 115

def tags
  self.class.parse_tags(@data['tags'])
end

#to_hashObject



201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/time_sheet/time/entry.rb', line 201

def to_hash
  return {
    'employee' => employee,
    'date' => date,
    'start' => start,
    'end' => self.end,
    'duration' => duration,
    'project' => project,
    'activity' => activity,
    'description' => description,
    'tags' => tags
  }
end

#to_rowObject



181
182
183
184
185
186
# File 'lib/time_sheet/time/entry.rb', line 181

def to_row
  [
    employee, date, start, self.end, duration.to_i, project, activity,
    description
  ]
end

#to_sObject



188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/time_sheet/time/entry.rb', line 188

def to_s
  values = [
    employee,
    date.strftime('%Y-%m-%d'),
    start.strftime('%H:%M'),
    self.end.strftime('%H:%M'),
    duration.to_i.to_s.rjust(4),
    project,
    activity,
    description
  ].join(' | ')
end

#valid!Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/time_sheet/time/entry.rb', line 163

def valid!
  if !@data['start']
    raise TimeSheet::Time::Exception.new('time entry has no start')
  end

  if duration <= 0
    raise TimeSheet::Time::Exception.new('time entry duration is 0 or less')
  end

  if (self.start >= self.end) && self.next
    raise TimeSheet::Time::Exception.new('time entry has no end')
  end

  if !employee
    raise TimeSheet::Time::Exception.new('no employee set')
  end
end

#valid?Boolean

Returns:

  • (Boolean)


152
153
154
155
156
157
158
159
160
161
# File 'lib/time_sheet/time/entry.rb', line 152

def valid?
  valid!
  true
rescue TimeSheet::Time::Exception => e
  self.exception = e
  false
rescue StandardError => e
  binding.pry if TimeSheet.options[:debug]
  false
end

#working_day?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/time_sheet/time/entry.rb', line 119

def working_day?
  !date.saturday? && !date.sunday? && !tags.include?('holiday')
end