Module: EmployeeWorkStatus
Overview
Day status, schedule preloading, and next-working-day logic.
Instance Method Summary
collapse
#activity_load_on_day, #can_take_activities_on_day?, #maximum_activities_per_day, #maximum_priority_tier_activities_per_day, #maximum_standard_tier_activities_per_day, #priority_tier_activities_ratio
Instance Method Details
#active_work_schedule(date) ⇒ Object
91
92
93
|
# File 'app/models/concerns/employee_work_status.rb', line 91
def active_work_schedule(date)
work_schedules.effective_on(date)
end
|
#capacity_ratio(date) ⇒ Object
80
81
82
83
84
85
86
87
88
|
# File 'app/models/concerns/employee_work_status.rb', line 80
def capacity_ratio(date)
date = date.to_date unless date.is_a?(Date)
day_status = day_status_employee_event(date)
return 1.0 if day_status.nil? || day_status == :working
return compute_partial_capacity(date) if day_status == :partial_timeoff
0.0
end
|
#current_company_holidays_array ⇒ Object
12
13
14
|
# File 'app/models/concerns/employee_work_status.rb', line 12
def current_company_holidays_array
@current_company_holidays_array ||= company.company_holidays.where(CompanyHoliday[:holiday_date].gteq(Date.current)).pluck(:holiday_date)
end
|
#day_employee_events(date) ⇒ Object
24
25
26
27
28
29
|
# File 'app/models/concerns/employee_work_status.rb', line 24
def day_employee_events(date)
date = date.to_date unless date.is_a?(Date)
return @preloaded_time_off_events[date] if @preloaded_time_off_events&.key?(date)
employee_events_loaded(date)
end
|
#day_status_employee_event(date) ⇒ Object
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'app/models/concerns/employee_work_status.rb', line 32
def day_status_employee_event(date)
evts = day_employee_events(date)
return if evts.blank?
wh = working_hours_on_date(date)
if evts.any? { |ev| ev.time_off_request.time_off_type_id == TimeOffType::BANKED_TIME_ID }
:working
elsif partial_day_pto_present?(evts, wh)
:partial_timeoff
else
evts.first.time_off_request.time_off_type.name.to_sym
end
end
|
#day_status_holiday_check(date) ⇒ Object
16
17
18
19
20
21
|
# File 'app/models/concerns/employee_work_status.rb', line 16
def day_status_holiday_check(date)
date = date.to_date unless date.is_a?(Date)
return :not_working_closed unless date.on_weekday?
:not_working_closed if current_company_holidays_array.include?(date)
end
|
#day_status_work_schedule(date) ⇒ Object
59
60
61
62
63
64
|
# File 'app/models/concerns/employee_work_status.rb', line 59
def day_status_work_schedule(date)
has_effective = work_schedules.loaded? ? effective_schedule_in_memory?(date) : work_schedules.effective_on(date).exists?
return unless has_effective && working_hours_on_date(date).zero?
:not_working_closed
end
|
#employee_events_loaded(start_date = nil) ⇒ Object
67
68
69
70
71
|
# File 'app/models/concerns/employee_work_status.rb', line 67
def employee_events_loaded(start_date = nil)
evts = TimeOffRequestDate.joins(:time_off_request).where(time_off_requests: { state: 'approved', employee_id: id })
evts = evts.where(date: start_date) if start_date
evts.distinct
end
|
#next_business_day(start_date = nil, offset = 1) ⇒ Object
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# File 'app/models/concerns/employee_work_status.rb', line 116
def next_business_day(start_date = nil, offset = 1)
start_date ||= Date.current
search_date = start_date.dup.to_date + offset.days
counter = 1
while work_status_on_day(search_date) == :not_working_closed
search_date += 1.day
if (counter += 1) > 30
search_date = nil
break
end
end
search_date
end
|
#next_business_day_closing_time(start_date = nil, offset = 1) ⇒ Object
130
131
132
133
|
# File 'app/models/concerns/employee_work_status.rb', line 130
def next_business_day_closing_time(start_date = nil, offset = 1)
dt = next_business_day(start_date, offset)
WorkingHours.advance_to_closing_time(dt)
end
|
#next_working_day(start_date = nil, offset = 1) ⇒ Object
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# File 'app/models/concerns/employee_work_status.rb', line 102
def next_working_day(start_date = nil, offset = 1)
start_date ||= Date.current
search_date = start_date.dup.to_date + offset.days
preload_time_off_events(search_date, search_date + 30.days)
attempts = 0
until working_on_day?(search_date)
search_date += 1.day
attempts += 1
raise no_working_day_within_search_limit_error if attempts > 730
end
search_date
end
|
#preload_time_off_events(start_date, end_date) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
|
# File 'app/models/concerns/employee_work_status.rb', line 135
def preload_time_off_events(start_date, end_date)
@preloaded_time_off_events ||= {}
events = TimeOffRequestDate.joins(:time_off_request)
.includes(time_off_request: :time_off_type)
.where(time_off_requests: { state: 'approved', employee_id: id })
.where(date: start_date..end_date)
.distinct
events.group_by(&:date).each { |date, evts| @preloaded_time_off_events[date] = evts }
(start_date..end_date).each { |date| @preloaded_time_off_events[date] ||= [] }
end
|
#preload_working_hours(start_date, end_date) ⇒ Object
147
148
149
150
151
152
153
154
155
|
# File 'app/models/concerns/employee_work_status.rb', line 147
def preload_working_hours(start_date, end_date)
@preloaded_working_hours ||= {}
schedules = schedules_for_preload(start_date, end_date)
hours_lookup = hours_by_schedule_and_wday(schedules)
(start_date..end_date).each do |date|
@preloaded_working_hours[date] = sum_working_hours_for_date(schedules, hours_lookup, date)
end
end
|
#work_status_on_day(date) ⇒ Object
74
75
76
77
|
# File 'app/models/concerns/employee_work_status.rb', line 74
def work_status_on_day(date)
date = date.to_date unless date.is_a?(Date)
day_status_holiday_check(date) || day_status_employee_event(date) || day_status_work_schedule(date) || :working
end
|
#working_hours_on_date(date) ⇒ Object
48
49
50
51
52
53
54
55
56
|
# File 'app/models/concerns/employee_work_status.rb', line 48
def working_hours_on_date(date)
date = date.to_date unless date.is_a?(Date)
return @preloaded_working_hours[date] if @preloaded_working_hours&.key?(date)
work_schedules.effective_on(date)
.joins(:work_schedule_days)
.where(work_schedule_days: { day_of_week: date.wday })
.sum('work_schedule_days.hours')
end
|
#working_on_day?(date) ⇒ Boolean
96
97
98
99
100
|
# File 'app/models/concerns/employee_work_status.rb', line 96
def working_on_day?(date)
date = date.to_date unless date.is_a?(Date)
ws = work_status_on_day(date)
ws == :working || (ws == :partial_timeoff && capacity_ratio(date).positive?)
end
|