Class: SchedulerAvailabilityService
- Inherits:
-
Object
- Object
- SchedulerAvailabilityService
- Defined in:
- app/services/scheduler_availability_service.rb
Constant Summary collapse
- SLOT_INCREMENT_MINUTES =
15
Instance Method Summary collapse
- #assign_host(eligible_employee_ids) ⇒ Object
- #available_slots ⇒ Object
- #has_availability? ⇒ Boolean
-
#initialize(booking_page, date, guest_timezone: 'America/Chicago', employee: nil, prefetched_gcal_busy: nil) ⇒ SchedulerAvailabilityService
constructor
prefetched_gcal_busy: optional Hash { employee_id => { Date => [end:] } } When provided, skips per-day Google Calendar API calls (used by available_dates batch).
- #verify_slot(starts_at) ⇒ Object
Constructor Details
#initialize(booking_page, date, guest_timezone: 'America/Chicago', employee: nil, prefetched_gcal_busy: nil) ⇒ SchedulerAvailabilityService
prefetched_gcal_busy: optional Hash { employee_id => { Date => [end:] } }
When provided, skips per-day Google Calendar API calls (used by available_dates batch).
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'app/services/scheduler_availability_service.rb', line 8 def initialize(booking_page, date, guest_timezone: 'America/Chicago', employee: nil, prefetched_gcal_busy: nil) @booking_page = booking_page @date = date.is_a?(Date) ? date : Date.parse(date.to_s) @guest_timezone = guest_timezone @duration = booking_page.duration_minutes @buffer_before = booking_page.buffer_before_minutes @buffer_after = booking_page.buffer_after_minutes @prefetched_gcal_busy = prefetched_gcal_busy @employees = if employee [employee] else booking_page.active_hosts.includes(:employee).map(&:employee) end end |
Instance Method Details
#assign_host(eligible_employee_ids) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 |
# File 'app/services/scheduler_availability_service.rb', line 71 def assign_host(eligible_employee_ids) return eligible_employee_ids.first if eligible_employee_ids.size == 1 booking_counts = SchedulerBooking.confirmed .where(scheduler_booking_page: @booking_page) .where(employee_id: eligible_employee_ids) .group(:employee_id) .count eligible_employee_ids.min_by { |id| booking_counts[id] || 0 } end |
#available_slots ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'app/services/scheduler_availability_service.rb', line 32 def available_slots return [] if @employees.empty? return [] if @date < Date.current return [] if @date > Date.current + @booking_page.max_days_ahead.days all_slots = {} @employees.each do |employee| slots = slots_for_employee(employee) slots.each do |slot_start| key = slot_start.to_i all_slots[key] ||= { starts_at: slot_start, employee_ids: [] } all_slots[key][:employee_ids] << employee.id end end all_slots.values .sort_by { |s| s[:starts_at] } .map do |slot| guest_time = slot[:starts_at].in_time_zone(@guest_timezone) { time: guest_time.strftime('%-l:%M %p'), starts_at: slot[:starts_at].iso8601, employee_ids: slot[:employee_ids] } end end |
#has_availability? ⇒ Boolean
24 25 26 27 28 29 30 |
# File 'app/services/scheduler_availability_service.rb', line 24 def has_availability? return false if @employees.empty? return false if @date < Date.current return false if @date > Date.current + @booking_page.max_days_ahead.days @employees.any? { |employee| slots_for_employee(employee).any? } end |
#verify_slot(starts_at) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'app/services/scheduler_availability_service.rb', line 60 def verify_slot(starts_at) starts_at = Time.zone.parse(starts_at) if starts_at.is_a?(String) ends_at = starts_at + @duration.minutes @employees.filter_map do |employee| next unless slot_available_for_employee?(employee, starts_at, ends_at) employee.id end end |