Class: User

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Gravtastic
Defined in:
app/models/user.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.with_unpaid_work_unitsObject

Scopes



25
26
27
# File 'app/models/user.rb', line 25

def self.with_unpaid_work_units
  select('distinct users.*').joins(:work_units).where(:work_units => {:paid => [nil, '']})
end

Instance Method Details

#admin?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'app/models/user.rb', line 81

def admin?
  @admin ||= has_role?(:admin)
end

#client?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'app/models/user.rb', line 73

def client?
  @client ||= has_role?(:client)
end

#clients_for_day(time) ⇒ Object



50
51
52
# File 'app/models/user.rb', line 50

def clients_for_day(time)
  work_units_for_day(time).map{|x| x.client}.uniq
end

#developer?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'app/models/user.rb', line 77

def developer?
  @developer ||= has_role?(:developer)
end

#entered_time_yesterday?Boolean

Returns:

  • (Boolean)


127
128
129
130
# File 'app/models/user.rb', line 127

def entered_time_yesterday?
  return true if !developer? || admin?
  previous_work_days_work_units.any?
end

#expected_hours(date) ⇒ Object

TODO: refactor this mess



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/models/user.rb', line 96

def expected_hours(date)
  raise "Date must be a date object" unless date.is_a?(Date)
  # no expected hours if the user has never worked
  return 0 unless work_units.present?
  # set the user's first day by the first work unit
  first_day = work_units.first.scheduled_at.to_date
  # no expected hours if their first day is in the future
  return 0 if first_day > date
  if first_day.year == date.year
    # if their first day was in the same year as the date
    # calculate the offset of the first week, incase they dont start on monday
    first_week_offset = first_day.cwday - 1
    # caculate total days from previous week, subtracting the first week offset
    days_from_prev_weeks = ((date.cweek - first_day.cweek) * 5) - first_week_offset
    # get the number of work days in the targeted week that have passed
    days_from_cur_week = [date.cwday, 5].min
  else
    # user has been here all year, count total work days in year
    days_from_prev_weeks = (date.cweek - 1) * 5
    days_from_cur_week = [date.cwday, 5].min
  end
  # calculate expected hours off of total expected days
  (days_from_prev_weeks + days_from_cur_week) * daily_target_hours
end

#hours_entered_for_day(time) ⇒ Object



58
59
60
61
62
63
64
# File 'app/models/user.rb', line 58

def hours_entered_for_day(time)
  hours = 0
  work_units_for_day(time).each do |w|
    hours += w.hours
  end
  hours
end

#initialsObject

Return the initials of the User



38
39
40
# File 'app/models/user.rb', line 38

def initials
  "#{first_name[0,1]}#{middle_initial}#{last_name[0,1]}".upcase
end

#lockedObject



85
86
87
# File 'app/models/user.rb', line 85

def locked
  locked_at?
end

#percentage_work_for(client, start_date, end_date) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
# File 'app/models/user.rb', line 136

def percentage_work_for(client, start_date, end_date)
  raise "client must be a Client instance" unless client.is_a?(Client)
  raise "Date must be a date object" unless start_date.is_a?(Date) && end_date.is_a?(Date)
  # note: I'm returning an integer here, as I think that is specific enough for the
  # reporting use case, this can easily be changed if future needs demand
  wu = work_units.scheduled_between(start_date.beginning_of_day, end_date.end_of_day)
  total_hours = wu.sum(:effective_hours)
  client_hours = wu.for_client(client).sum(:effective_hours)
  # Dividing by 0 is bad, mkay?
  total_hours == 0 ? 0 : ((100 * client_hours)/total_hours).round
end

#previous_work_days_work_unitsObject



132
133
134
# File 'app/models/user.rb', line 132

def previous_work_days_work_units
  work_units_between(Date.current.prev_working_day.beginning_of_day, Date.current.prev_working_day.end_of_day)
end

#pto_hours_left(date) ⇒ Object



89
90
91
92
93
# File 'app/models/user.rb', line 89

def pto_hours_left(date)
  raise "Date must be a date object" unless date.is_a?(Date)
  time = date.to_time_in_current_zone
  SiteSettings.first.total_yearly_pto_per_user - work_units.pto.scheduled_between(time.beginning_of_year, time).sum(:hours)
end

#target_hours_offset(date) ⇒ Object



121
122
123
124
125
# File 'app/models/user.rb', line 121

def target_hours_offset(date)
  raise "Date must be a date object" unless date.is_a?(Date)
  worked_hours = WorkUnit.for_user(self).scheduled_between(date.beginning_of_year, date.end_of_day).sum(:hours)
  worked_hours - expected_hours(date)
end

#to_sObject



69
70
71
# File 'app/models/user.rb', line 69

def to_s
  "#{first_name.capitalize} #{middle_initial.capitalize} #{last_name.capitalize}"
end

#unpaid_work_unitsObject



65
66
67
# File 'app/models/user.rb', line 65

def unpaid_work_units
  work_units.unpaid
end

#work_units_between(start_time, end_time) ⇒ Object



42
43
44
# File 'app/models/user.rb', line 42

def work_units_between(start_time, end_time)
  work_units.scheduled_between(start_time.beginning_of_day, end_time.end_of_day)
end

#work_units_for_day(time) ⇒ Object



46
47
48
# File 'app/models/user.rb', line 46

def work_units_for_day(time)
  work_units.scheduled_between(time.beginning_of_day, time.end_of_day)
end

#work_units_for_week(time) ⇒ Object



54
55
56
# File 'app/models/user.rb', line 54

def work_units_for_week(time)
  work_units.scheduled_between(time.beginning_of_week, time.end_of_week)
end