Class: EmployeeWorkSchedule

Inherits:
ApplicationRecord show all
Defined in:
app/models/employee_work_schedule.rb

Overview

== Schema Information

Table name: employee_work_schedules
Database name: primary

id :integer not null, primary key
breaks :text
friday_from :datetime
friday_to :datetime
holidays :text
hours :jsonb
hours_legacy :text
lunch :datetime
monday_from :datetime
monday_to :datetime
saturday_from :datetime
saturday_to :datetime
sunday_from :datetime
sunday_to :datetime
thursday_from :datetime
thursday_to :datetime
time_zone :string
tuesday_from :datetime
tuesday_to :datetime
wednesday_from :datetime
wednesday_to :datetime
week :datetime
work_timezone :integer default(1)
created_at :datetime not null
updated_at :datetime not null
employee_id :integer

Indexes

employee_work_schedules_employee_id_idx (employee_id)

Foreign Keys

fk_rails_... (employee_id => parties.id) ON DELETE => cascade

Constant Summary collapse

WORK_TIMEZONE_PLACEHOLDER =

DB default for work_timezone; rows often keep this without a real selection.
Daily Focus prompt hints skip this id so we do not emit noisy "work_timezone id 1" lines.

1

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Belongs to collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Class Method Details

.work_schedule_time_selectvoid

This method returns an undefined value.



54
55
56
57
58
59
60
# File 'app/models/employee_work_schedule.rb', line 54

def self.work_schedule_time_select
  result = []
  (Time.zone.parse('00:00').to_i..Time.zone.parse('23:45').to_i).step(15.minutes.to_i) do |time|
    result << [Time.zone.at(time).strftime('%I:%M %P'), Time.zone.at(time).strftime('%H:%M')]
  end
  result
end

Instance Method Details

#employeeEmployee?

Returns:



49
# File 'app/models/employee_work_schedule.rb', line 49

belongs_to :employee, inverse_of: :employee_work_schedules, optional: true

#lunch_hours_a_weekvoid

This method returns an undefined value.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'app/models/employee_work_schedule.rb', line 165

def lunch_hours_a_week
  accumulated = 0
  hours.each_key do |weekday|
    hours[weekday][:lunch].each do |range|
      accumulated += begin
        range[1].to_s.to_time
      rescue StandardError
        0
      end - begin
        range[0].to_s.to_time
      rescue StandardError
        0
      end
    end
  end
  accumulated
end

#lunch_on_a_day(day) ⇒ void

Parameters:

  • day (Object)
  • day (Object)

Returns:

  • (void)
  • (void)


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'app/models/employee_work_schedule.rb', line 210

def lunch_on_a_day(day)
  hash = hours[day.to_sym][:lunch]
  accumulated = 0
  hash.each do |range|
    accumulated += begin
      range[1].to_s.to_time
    rescue StandardError
      0
    end - begin
      range[0].to_s.to_time
    rescue StandardError
      0
    end
  end
  accumulated
end

#shift_start_minute_on(date) ⇒ Integer?

First minute this schedule has the employee working on +date+.

hours stores a day as discrete work ranges with breaks already carved out
(=> {"work" => {"07:30" => "11:30", "12:30" => "16:30"}}), so the
shift starts at the earliest of them.

Parameters:

  • date (Date)

Returns:

  • (Integer, nil)

    minutes from midnight, nil when not scheduled



70
71
72
73
74
75
76
77
78
79
# File 'app/models/employee_work_schedule.rb', line 70

def shift_start_minute_on(date)
  ranges = hours&.dig(date.strftime('%a').downcase, 'work')
  return nil if ranges.blank?

  starts = ranges.keys.filter_map do |hhmm|
    hour, minute = hhmm.to_s.split(':')
    ((hour.to_i * 60) + minute.to_i) if hour.present? && minute.present?
  end
  starts.min
end

#total_hours_on_a_day(day) ⇒ void

Parameters:

  • day (Object)
  • day (Object)

Returns:

  • (void)
  • (void)


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'app/models/employee_work_schedule.rb', line 187

def total_hours_on_a_day(day)
  hash = hours[day.to_sym]
  accumulated = 0
  hash.each_key do |slot|
    hash[slot].each do |range|
      accumulated += begin
        range[1].to_s.to_time
      rescue StandardError
        0
      end - begin
        range[0].to_s.to_time
      rescue StandardError
        0
      end
    end
  end
  accumulated
end

#working_hours_a_weekvoid

This method returns an undefined value.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'app/models/employee_work_schedule.rb', line 146

def working_hours_a_week
  accumulated = 0
  hours.each_key do |weekday|
    hours[weekday][:work].each do |range|
      accumulated += begin
        range[1].to_s.to_time
      rescue StandardError
        0
      end - begin
        range[0].to_s.to_time
      rescue StandardError
        0
      end
    end
  end
  accumulated
end

#working_hours_in_timerange(date, from, to, avoid_lunch) ⇒ void

Parameters:

  • date (Object)
  • from (Object)
  • to (Object)
  • avoid_lunch (Object)
  • date (Object)
  • from (Object)
  • to (Object)
  • avoid_lunch (Object)

Returns:

  • (void)
  • (void)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/models/employee_work_schedule.rb', line 91

def working_hours_in_timerange(date, from, to, avoid_lunch)
  day_duration = 0
  lunch = begin
    lunch_on_a_day(date.to_date.strftime("%a").downcase)
  rescue StandardError
    0
  end
  hash = hours
  hash[date.to_date.strftime("%a").downcase.to_sym].each_key do |slot|
    hash[date.to_date.strftime("%a").downcase.to_sym][slot].each do |range|
      array1 = (range[0].to_s.to_time.to_i..range[1].to_s.to_time.to_i).step(1.minute.to_i).to_a
      array2 = (from.to_time.to_i..to.to_time.to_i).step(1.minute.to_i).to_a
      array3 = (array1 & array2)
      array3.pop
      day_duration += array3.size * 60 # if slot.to_s == "work"
      # lunch += (array3.size)*60 if slot.to_s == "lunch"
    end
  end
  if day_duration - lunch < 0
    avoid_lunch == "true" ? 0 : day_duration
  else
    avoid_lunch == "true" ? day_duration - lunch : day_duration
  end
end

#working_seconds_on_a_day(day, humanized = true) ⇒ void

Parameters:

  • day (Object)
  • humanized (Object) (defaults to: true)
  • day (Object)
  • humanized (Object) (defaults to: true)

Returns:

  • (void)
  • (void)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/employee_work_schedule.rb', line 122

def working_seconds_on_a_day(day, humanized = true)
  working_hours = hours.dig(day.to_sym, :work)
  return 0 if working_hours.blank?

  accumulated = 0
  working_hours.each do |range|
    accumulated += begin
      range[1].to_s.to_time
    rescue StandardError
      0
    end - begin
      range[0].to_s.to_time
    rescue StandardError
      0
    end
  end
  if humanized
    EmployeeTimeOffsController.helpers.human_duration(accumulated)
  else
    accumulated
  end
end

#working_status_on_a_day(date) ⇒ void

Parameters:

  • date (Object)
  • date (Object)

Returns:

  • (void)
  • (void)


231
232
233
# File 'app/models/employee_work_schedule.rb', line 231

def working_status_on_a_day(date)
  :not_working_closed if hours[date.strftime("%a").downcase.to_sym][:work].keys.empty?
end