Class: SchedulerGoogleCalendarService

Inherits:
Object
  • Object
show all
Defined in:
app/services/scheduler_google_calendar_service.rb

Constant Summary collapse

CALENDAR_ID =
'primary'
TIMEZONE =
'America/Chicago'

Instance Method Summary collapse

Constructor Details

#initialize(employee) ⇒ SchedulerGoogleCalendarService

Returns a new instance of SchedulerGoogleCalendarService.



7
8
9
10
11
# File 'app/services/scheduler_google_calendar_service.rb', line 7

def initialize(employee)
  @employee = employee
  @client = TimeOffRequests::GoogleAuthService.authorize(employee)
  setup_service if @client
end

Instance Method Details

#busy_times(date) ⇒ Object

Returns an array of busy time ranges [Time, end: Time, ...] for the given date



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'app/services/scheduler_google_calendar_service.rb', line 18

def busy_times(date)
  return [] unless connected?

  tz = ActiveSupport::TimeZone[TIMEZONE]
  time_min = tz.local(date.year, date.month, date.day).iso8601
  time_max = tz.local(date.year, date.month, date.day, 23, 59, 59).iso8601

  events = fetch_events(time_min, time_max)
  events.filter_map do |event|
    next if event.transparency == 'transparent'

    start_time = parse_event_time(event.start)
    end_time = parse_event_time(event.end)
    next unless start_time && end_time

    { start: start_time, end: end_time }
  end
rescue Google::Apis::AuthorizationError
  refresh_and_retry(:busy_times, date)
rescue Google::Apis::ClientError => e
  Rails.logger.error("SchedulerGoogleCalendarService#busy_times failed for #{@employee.email}: #{e.message}")
  []
end

#busy_times_range(start_date, end_date) ⇒ Object

Single API call to fetch busy times for an entire date range.
Returns { Date => [Time, end: Time, ...], ... }



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'app/services/scheduler_google_calendar_service.rb', line 56

def busy_times_range(start_date, end_date)
  return {} unless connected?

  tz = ActiveSupport::TimeZone[TIMEZONE]
  time_min = tz.local(start_date.year, start_date.month, start_date.day).iso8601
  time_max = tz.local(end_date.year, end_date.month, end_date.day, 23, 59, 59).iso8601

  events = fetch_events(time_min, time_max)
  result = Hash.new { |h, k| h[k] = [] }

  events.each do |event|
    next if event.transparency == 'transparent'

    if event.start&.date
      event_start_date = event.start.date.is_a?(Date) ? event.start.date : Date.parse(event.start.date)
      event_end_date = event.end.date.is_a?(Date) ? event.end.date : Date.parse(event.end.date)
      (event_start_date...event_end_date).each do |d|
        next if d < start_date || d > end_date

        day_start = tz.local(d.year, d.month, d.day)
        result[d] << { start: day_start, end: day_start + 1.day }
      end
    else
      start_time = parse_event_time(event.start)
      end_time = parse_event_time(event.end)
      next unless start_time && end_time

      result[start_time.to_date] << { start: start_time, end: end_time }
    end
  end

  result
rescue Google::Apis::AuthorizationError
  refresh_and_retry(:busy_times_range, start_date, end_date)
rescue Google::Apis::ClientError => e
  Rails.logger.error("SchedulerGoogleCalendarService#busy_times_range failed for #{@employee.email}: #{e.message}")
  {}
end

#connected?Boolean

Returns:

  • (Boolean)


13
14
15
# File 'app/services/scheduler_google_calendar_service.rb', line 13

def connected?
  @client.present?
end

#create_event(booking) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
# File 'app/services/scheduler_google_calendar_service.rb', line 42

def create_event(booking)
  return unless connected?

  event = build_event(booking)
  created = @service.insert_event(CALENDAR_ID, event, send_updates: 'all')
  booking.update_column(:google_event_id, created.id)
rescue Google::Apis::AuthorizationError
  refresh_and_retry(:create_event, booking)
rescue Google::Apis::ClientError => e
  Rails.logger.error("SchedulerGoogleCalendarService#create_event failed: #{e.message}")
end

#delete_event(google_event_id) ⇒ Object



106
107
108
109
110
111
112
113
114
# File 'app/services/scheduler_google_calendar_service.rb', line 106

def delete_event(google_event_id)
  return unless connected? && google_event_id.present?

  @service.delete_event(CALENDAR_ID, google_event_id)
rescue Google::Apis::AuthorizationError
  refresh_and_retry(:delete_event, google_event_id)
rescue Google::Apis::ClientError => e
  Rails.logger.error("SchedulerGoogleCalendarService#delete_event failed: #{e.message}")
end

#update_event(booking) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'app/services/scheduler_google_calendar_service.rb', line 95

def update_event(booking)
  return create_event(booking) unless connected? && booking.google_event_id.present?

  event = build_event(booking)
  @service.patch_event(CALENDAR_ID, booking.google_event_id, event, send_updates: 'all')
rescue Google::Apis::AuthorizationError
  refresh_and_retry(:update_event, booking)
rescue Google::Apis::ClientError => e
  Rails.logger.error("SchedulerGoogleCalendarService#update_event failed: #{e.message}")
end