Class: QueueCoverage::Rep
- Inherits:
-
Data
- Object
- Data
- QueueCoverage::Rep
- Defined in:
- app/services/queue_coverage.rb
Overview
One rep's day.
+scheduled+ is the shift before meetings come out; +intervals+ is what is
left after. Keeping both is what lets the grid say why a rep is off queue
at 12:00 — lunch reads differently from a meeting, and both read differently
from "their shift has not started". +meetings+ and +other_queues+ drive the
cell state and the dedicated/shared split; +calendar_unreadable+ marks a rep
whose grant we could not read, so "no meetings" is never read as "no data".
Instance Attribute Summary collapse
-
#calendar_unreadable ⇒ Object
readonly
Returns the value of attribute calendar_unreadable.
-
#code ⇒ Object
readonly
Returns the value of attribute code.
-
#employee ⇒ Object
readonly
Returns the value of attribute employee.
-
#intervals ⇒ Object
readonly
Returns the value of attribute intervals.
-
#meetings ⇒ Object
readonly
Returns the value of attribute meetings.
-
#other_queues ⇒ Object
readonly
Returns the value of attribute other_queues.
-
#scheduled ⇒ Object
readonly
Returns the value of attribute scheduled.
-
#time_off ⇒ Object
readonly
Returns the value of attribute time_off.
-
#work_status ⇒ Object
readonly
Returns the value of attribute work_status.
Instance Method Summary collapse
-
#dedicated? ⇒ Boolean
True when this queue is the rep's only live queue.
-
#off? ⇒ Boolean
True when the rep has no queue time at all today.
- #on_queue_at?(minute) ⇒ Boolean
-
#reason_at(minute) {|a| ... } ⇒ String?
Why this rep is not on queue at +minute+, for the cell popover.
-
#state_at(minute) ⇒ Symbol
Why this rep is (or is not) on queue at +minute+ — one cell of the grid.
-
#working? ⇒ Boolean
True when the rep is working at all today.
Instance Attribute Details
#calendar_unreadable ⇒ Object (readonly)
Returns the value of attribute calendar_unreadable
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def calendar_unreadable @calendar_unreadable end |
#code ⇒ Object (readonly)
Returns the value of attribute code
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def code @code end |
#employee ⇒ Object (readonly)
Returns the value of attribute employee
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def employee @employee end |
#intervals ⇒ Object (readonly)
Returns the value of attribute intervals
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def intervals @intervals end |
#meetings ⇒ Object (readonly)
Returns the value of attribute meetings
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def meetings @meetings end |
#other_queues ⇒ Object (readonly)
Returns the value of attribute other_queues
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def other_queues @other_queues end |
#scheduled ⇒ Object (readonly)
Returns the value of attribute scheduled
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def scheduled @scheduled end |
#time_off ⇒ Object (readonly)
Returns the value of attribute time_off
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def time_off @time_off end |
#work_status ⇒ Object (readonly)
Returns the value of attribute work_status
46 47 48 |
# File 'app/services/queue_coverage.rb', line 46 def work_status @work_status end |
Instance Method Details
#dedicated? ⇒ Boolean
Returns true when this queue is the rep's only live queue.
49 50 |
# File 'app/services/queue_coverage.rb', line 49 def dedicated? = other_queues.zero? # @return [Boolean] true when the rep has no queue time at all today |
#off? ⇒ Boolean
Returns true when the rep has no queue time at all today.
51 52 |
# File 'app/services/queue_coverage.rb', line 51 def off? = intervals.empty? # @return [Boolean] true when the rep is working at all today |
#on_queue_at?(minute) ⇒ Boolean
56 |
# File 'app/services/queue_coverage.rb', line 56 def on_queue_at?(minute) = covers?(intervals, minute) |
#reason_at(minute) {|a| ... } ⇒ String?
Why this rep is not on queue at +minute+, for the cell popover. The grid
shows plain coloured squares, so this is where "and why?" lives.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'app/services/queue_coverage.rb', line 82 def reason_at(minute) case state_at(minute) when :on then nil when :meeting window = meetings.find { |(from, to)| from <= minute && to > minute } # Calendar titles are deliberately never read. "In a meeting #{yield(window.first)}-#{yield(window.last)}" when :break shift = scheduled.map { |(from, to)| "#{yield(from)}-#{yield(to)}" }.join(', ') # "Lunch", not "break": EmployeeWorkSchedule#hours stores the gap under # a +lunch+ key, and that is the word the team uses for it. "Scheduled lunch between shifts (#{shift})" when :not_working [work_status.to_s.humanize, time_off].compact_blank.join(' - ').presence else "Outside their shift (#{yield(scheduled.first.first)}-#{yield(scheduled.last.last)})" end end |
#state_at(minute) ⇒ Symbol
Why this rep is (or is not) on queue at +minute+ — one cell of the grid.
Order matters, and :meeting is gated on the shift: calendar windows are
clipped to the day, not to this rep's hours, so a 7am dentist appointment
or a lunchtime call would otherwise read MTG on a grid another rep widened
— implying queue time was lost when the rep was never due on queue.
67 68 69 70 71 72 73 74 |
# File 'app/services/queue_coverage.rb', line 67 def state_at(minute) return :not_working unless working? return :on if covers?(intervals, minute) return :meeting if covers?(meetings, minute) && covers?(scheduled, minute) return :break if minute >= scheduled.first.first && minute < scheduled.last.last :off_shift end |
#working? ⇒ Boolean
Returns true when the rep is working at all today.
53 54 55 |
# File 'app/services/queue_coverage.rb', line 53 def working? = scheduled.any? # @param minute [Integer] minutes from midnight # @return [Boolean] |