diff --git a/drivers/mulesoft/calendar_exporter.cr b/drivers/mulesoft/calendar_exporter.cr index 1d7ff39f00..d61b6c3091 100644 --- a/drivers/mulesoft/calendar_exporter.cr +++ b/drivers/mulesoft/calendar_exporter.cr @@ -5,8 +5,8 @@ require "place_calendar" class MuleSoft::CalendarExporter < PlaceOS::Driver descriptive_name "MuleSoft Bookings to Calendar Events Exporter" - generic_name :Bookings - description %(Retrieves and creates bookings using the MuleSoft API) + generic_name :MulesoftExport + description %(Listens for new MuleSoft bookings and creates matching Events in a Calendar) default_settings({ calendar_time_zone: "Australia/Sydney", @@ -34,12 +34,13 @@ class MuleSoft::CalendarExporter < PlaceOS::Driver @time_zone_string = setting?(String, :calendar_time_zone).presence @time_zone = Time::Location.load(@time_zone_string.not_nil!) if @time_zone_string - self[:timezone] = Time.local.to_s + self[:timezone] = @time_zone.to_s subscription = system.subscribe(:Bookings_1, :bookings) do |_subscription, mulesoft_bookings| - logger.debug { "DETECTED changed in Mulesoft Bookings.." } + logger.debug { "DETECTED change in Mulesoft Bookings..." } @bookings = Array(Hash(String, Int64 | String | Nil)).from_json(mulesoft_bookings) logger.debug { "#{@bookings.size} bookings in total" } + self[:total_bookings] = @bookings.size update_events @bookings.each { |b| export_booking(b) } @@ -57,6 +58,7 @@ class MuleSoft::CalendarExporter < PlaceOS::Driver logger.debug { "FETCHING existing Calendar events..." } @existing_events = fetch_events() logger.debug { "#{@existing_events.size} events in total" } + self[:total_events] = @existing_events.size end protected def fetch_events(past_span : Time::Span = 14.days, future_span : Time::Span = 14.days) @@ -71,10 +73,11 @@ class MuleSoft::CalendarExporter < PlaceOS::Driver ).get.as_a end - protected def export_booking(booking : Hash(String, Int64 | String | Nil)) - # Mulesoft booking titles are often nil. Use the body instead in this case - booking["title"] = booking["body"] if booking["title"].nil? - booking["title"] = "#{booking["recurring_master_id"]} #{booking["title"]}" + protected def export_booking(mulesoft_booking : Hash(String, Int64 | String | Nil)) + # The resulting Calendar Event is to be slightly different to the Mulesoft Booking, so clone here and transform + booking = mulesoft_booking.clone + # Add the course code to the front of the booking title/body + booking["title"] = "#{booking["recurring_master_id"]} #{booking["title"] || booking["body"]}" logger.debug { "Checking for existing events that match: #{booking}" } unless event_already_exists?(booking, @existing_events) @@ -88,28 +91,25 @@ class MuleSoft::CalendarExporter < PlaceOS::Driver attendees: [@just_this_system], location: system.name.not_nil!, } - logger.debug { ">>> EXPORTING booking #{new_event}" } + logger.debug { ">>> EXPORTING booking as: #{new_event}" } calendar.create_event(**new_event) end end - protected def event_already_exists?(new_event : Hash(String, Int64 | String | Nil), existing_events : Array(JSON::Any)) - existing_events.each do |existing_event| - return true if events_match?(new_event, existing_event.as_h) - end - false + protected def event_already_exists?(booking : Hash(String, Int64 | String | Nil), existing_events : Array(JSON::Any)) + existing_events.any? { |existing_event| booking_matches_event?(booking, existing_event.as_h) } end - protected def events_match?(event_a : Hash(String, Int64 | String | Nil), event_b : Hash(String, JSON::Any)) - event_a.select("event_start", "event_end", "title") == event_b.select("event_start", "event_end", "title") + protected def booking_matches_event?(booking : Hash(String, Int64 | String | Nil), event : Hash(String, JSON::Any)) + booking.select("event_start", "event_end", "title") == event.select("event_start", "event_end", "title") end def delete_all_events(past_days : Int32 = 14, future_days : Int32 = 14) events = fetch_events(past_span: past_days.days, future_span: future_days.days) - event_ids = events.map { |e| e["id"] } - event_ids.each do |event_id| - calendar.delete_event(calendar_id: system.email.not_nil!, event_id: event_id) + events.each do |event| + calendar.delete_event(calendar_id: system.email.not_nil!, event_id: event["id"]) end - "Deleted #{event_ids.size} events" + logger.debug { "DELETED #{events.size} events" } + events.size end end