require 'seatsio/util' module Seatsio module_function class Chart attr_reader :id, :key, :status, :name, :published_version_thumbnail_url, :draft_version_thumbnail_url, :events, :tags, :archived, :categories, :validation, :social_distancing_rulesets def initialize(data) @id = data['id'] @key = data['key'] @status = data['status'] @name = data['name'] @published_version_thumbnail_url = data['publishedVersionThumbnailUrl'] @draft_version_thumbnail_url = data['draftVersionThumbnailUrl'] @events = Event.create_list(data['events']) if data['events'] @tags = data['tags'] @archived = data['archived'] @validation = data['validation'] @social_distancing_rulesets = data['socialDistancingRulesets'].map { |key, r| [key, SocialDistancingRuleset.new(r['name'], number_of_disabled_seats_to_the_sides: r['numberOfDisabledSeatsToTheSides'], disable_seats_in_front_and_behind: r['disableSeatsInFrontAndBehind'], disable_diagonal_seats_in_front_and_behind: r['disableDiagonalSeatsInFrontAndBehind'], number_of_disabled_aisle_seats: r['numberOfDisabledAisleSeats'], max_group_size: r['maxGroupSize'], max_occupancy_absolute: r['maxOccupancyAbsolute'], max_occupancy_percentage: r['maxOccupancyPercentage'], one_group_per_table: r['oneGroupPerTable'], fixed_group_layout: r['fixedGroupLayout'], disabled_seats: r['disabledSeats'], enabled_seats: r['enabledSeats'], index: r['index'])] }.to_h end end class ChartValidationResult attr_reader :errors, :warnings def initialize(data) @errors = data['errors'] @warnings = data['warnings'] end end class ChartDraft < Chart attr_reader :version def initialize(data) super(data) @version = data['version'] end end class ForSaleConfig attr_reader :for_sale, :objects, :area_places, :categories def initialize(data) if data @for_sale = data['forSale'] @objects = data['objects'] @area_places = data['areaPlaces'] @categories = data['categories'] end end end class Category attr_reader :key, :label, :color, :accessible def initialize(key, label, color, accessible) @key = key @label = label @color = color @accessible = accessible end def self.from_json(data) if data Category.new(data['key'], data['label'], data['color'], data['accessible']) end end def self.create_list(list = []) result = [] list.each do |item| result << Category.from_json(item) end result end def == (other) key == other.key && label == other.label && color == other.color && accessible == other.accessible end end class TableBookingConfig attr_reader :mode, :tables def initialize(mode, tables = nil) @mode = mode @tables = tables end def self.inherit TableBookingConfig.new('INHERIT') end def self.all_by_seat TableBookingConfig.new('ALL_BY_SEAT') end def self.all_by_table TableBookingConfig.new('ALL_BY_TABLE') end def self.custom(tables) TableBookingConfig.new('CUSTOM', tables) end def self.from_json(data) if data TableBookingConfig.new(data['mode'], data['tables']) end end end class Channel attr_reader :key, :name, :color, :index, :objects def initialize(key, name, color, index, objects) @key = key @name = name @color = color @index = index @objects = objects end def == (other) key == other.key && name == other.name && color == other.color && index == other.index && objects == other.objects end end class Event attr_accessor :id, :key, :chart_key, :supports_best_available, :table_booking_config, :for_sale_config, :created_on, :updated_on, :channels, :social_distancing_ruleset_key, :is_top_level_season, :is_partial_season, :is_event_in_season, :top_level_season_key, :social_distancing_ruleset_key, :object_categories, :categories def initialize(data) @id = data['id'] @key = data['key'] @chart_key = data['chartKey'] @supports_best_available = data['supportsBestAvailable'] @table_booking_config = TableBookingConfig::from_json(data['tableBookingConfig']) @for_sale_config = ForSaleConfig.new(data['forSaleConfig']) if data['forSaleConfig'] @created_on = parse_date(data['createdOn']) @updated_on = parse_date(data['updatedOn']) @channels = data['channels'].map { |d| Channel.new(d['key'], d['name'], d['color'], d['index'], d['objects']) } if data['channels'] @social_distancing_ruleset_key = data['socialDistancingRulesetKey'] @is_top_level_season = data['isTopLevelSeason'] @is_partial_season = data['isPartialSeason'] @is_event_in_season = data['isEventInSeason'] @top_level_season_key = data['topLevelSeasonKey'] @object_categories = data['objectCategories'] @categories = Category.create_list(data['categories']) if data['categories'] end def is_season false end def self.from_json(data) if data['isSeason'] Season.new(data) else Event.new(data) end end def self.create_list(list = []) result = [] list.each do |item| result << Event.from_json(item) end result end end class Season < Event attr_accessor :partial_season_keys, :events def initialize(data) super(data) @partial_season_keys = data['partialSeasonKeys'] @events = data['events'] ? Event.create_list(data['events']) : nil end def is_season true end end class Events attr_accessor :events def initialize(data) @events = Event.create_list(data['events']) if data['events'] end end class APIResponse attr_reader :next_page_starts_after, :previous_page_ends_before, :items def initialize(data) @next_page_starts_after = data.fetch('next_page_starts_after', nil).to_i @previous_page_ends_before = data.fetch('previous_page_ends_before', nil).to_i @items = data.fetch('items', []) end end class Subaccount attr_reader :id, :secret_key, :designer_key, :public_key, :name, :active def initialize(data) @id = data['id'] @public_key = data['publicKey'] @secret_key = data['secretKey'] @designer_key = data['designerKey'] @name = data['name'] @active = data['active'] end end class Workspace attr_reader :id, :name, :key, :secret_key, :is_test, :is_active, :is_default def initialize(data) @id = data['id'] @name = data['name'] @key = data['key'] @secret_key = data['secretKey'] @is_test = data['isTest'] @is_active = data['isActive'] @is_default = data['isDefault'] end end class ChangeObjectStatusResult attr_reader :objects def initialize(data) @objects = Seatsio.to_object_details(data['objects']); end end class ChangeObjectStatusInBatchResult attr_reader :results def initialize(data) @results = data['results'].map { |r| ChangeObjectStatusResult.new(r) } end end class HoldToken attr_reader :hold_token, :expires_at, :expires_in_seconds, :workspace_key def initialize(data) @hold_token = data['holdToken'] @expires_at = Time.parse(data['expiresAt']) @expires_in_seconds = data['expiresInSeconds'] @workspace_key = data['workspaceKey'] end end class BestAvailableObjects attr_reader :next_to_each_other, :objects, :object_details def initialize(data) @next_to_each_other = data['nextToEachOther'] @objects = data['objects'] @object_details = Seatsio.to_object_details(data['objectDetails']) end end class ChartObjectInfo attr_reader :label, :labels, :ids, :category_key, :category_label, :section, :entrance, :capacity, :object_type, :left_neighbour, :right_neighbour, :book_as_a_whole, :distance_to_focal_point, :num_seats def initialize(data) @label = data['label'] @labels = data['labels'] @ids = data['ids'] @category_label = data['categoryLabel'] @category_key = data['categoryKey'] @section = data['section'] @entrance = data['entrance'] @capacity = data['capacity'] @object_type = data['objectType'] @left_neighbour = data['leftNeighbour'] @right_neighbour = data['rightNeighbour'] @book_as_a_whole = data['bookAsAWhole'] @distance_to_focal_point = data['distanceToFocalPoint'] @num_seats = data['numSeats'] end end class ChartReport attr_reader :items def initialize(data) items = {} data.each do |key, values| items[key] = [] values.each do |value| items[key] << ChartObjectInfo.new(value) end end @items = items end end class EventReport attr_reader :items def initialize(data) if data.is_a? Array items = [] data.each do |item| items << EventObjectInfo.new(item) end @items = items elsif data.nil? @items = [] else items = {} data.each do |key, values| items[key] = [] values.each do |value| items[key] << EventObjectInfo.new(value) end end @items = items end end end class EventObjectInfo FREE = 'free' BOOKED = 'booked' HELD = 'reservedByToken' attr_reader :labels, :ids, :label, :order_id, :extra_data, :capacity, :status, :category_key, :entrance, :object_type, :hold_token, :category_label, :ticket_type, :num_booked, :num_free, :num_held, :for_sale, :section, :is_accessible, :is_companion_seat, :has_restricted_view, :displayed_object_type, :left_neighbour, :right_neighbour, :is_available, :is_disabled_by_social_distancing, :channel, :book_as_a_whole, :distance_to_focal_point, :holds, :num_seats def initialize(data) @status = data['status'] @label = data['label'] @labels = data['labels'] @ids = data['ids'] @category_label = data['categoryLabel'] @category_key = data['categoryKey'] @ticket_type = data['ticketType'] @order_id = data['orderId'] @for_sale = data['forSale'] @hold_token = data['holdToken'] @section = data['section'] @entrance = data['entrance'] @num_booked = data['numBooked'] @num_free = data['numFree'] @num_held = data['numHeld'] @capacity = data['capacity'] @object_type = data['objectType'] @extra_data = data['extraData'] @is_accessible = data['isAccessible'] @is_companion_seat = data['isCompanionSeat'] @has_restricted_view = data['hasRestrictedView'] @displayed_object_type = data['displayedObjectType'] @left_neighbour = data['leftNeighbour'] @right_neighbour = data['rightNeighbour'] @is_available = data['isAvailable'] @is_disabled_by_social_distancing = data['isDisabledBySocialDistancing'] @channel = data['channel'] @book_as_a_whole = data['bookAsAWhole'] @distance_to_focal_point = data['distanceToFocalPoint'] @holds = data['holds'] @num_seats = data['numSeats'] end end class UsageSummaryForAllMoths attr_reader :items def initialize(data) items = [] data.each do |item| items << UsageSummaryForMonth.new(item) end @items = items end end class UsageSummaryForMonth def initialize(data) @month = Month.from_json(data['month']) @num_used_objects = data['numUsedObjects'] @num_first_bookings = data['numFirstBookings'] @num_first_bookings_by_status = data['numFirstBookingsByStatus'] @num_first_bookings_or_selections = data['numFirstBookingsOrSelections'] end end class UsageDetails attr_reader :workspace, :usage_by_chart def initialize(data) @workspace = data['workspace'] @usage_by_chart = data['usageByChart'].map { |usage| UsageByChart.new(usage) } end end class UsageByChart attr_reader :chart, :usage_by_event def initialize(data) @chart = data['chart'] ? UsageChart.new(data['chart']) : nil @usage_by_event = data['usageByEvent'].map { |usage| UsageByEvent.new(usage) } end end class UsageChart attr_reader :name, :key def initialize(data) @name = data['name'] @key = data['key'] end end class UsageByEvent attr_reader :event, :num_used_objects, :num_first_bookings, :num_object_selections def initialize(data) @event = UsageEvent.new(data['event']) @num_used_objects = data['numUsedObjects'] @num_first_bookings = data['numFirstBookings'] @num_object_selections = data['numObjectSelections'] end end class UsageEvent attr_reader :id, :key def initialize(data) @id = data['id'] @key = data['key'] end end class UsageForObject attr_reader :object, :num_first_bookings, :first_booking_date, :num_first_bookings, :num_first_bookings_or_selections def initialize(data) @object = data['object'] @num_first_bookings = data['numFirstBookings'] @first_booking_date = data['firstBookingDate'] ? DateTime.iso8601(data['firstBookingDate']) : nil @num_first_selections = data['numFirstSelections'] @num_first_bookings_or_selections = data['numFirstBookingsOrSelections'] end end class Month attr_reader :year, :month def self.from_json(data) @year = data['year'] @month = data['month'] self end def initialize(year, month) @year = year @month = month end def serialize @year.to_s + "-" + @month.to_s.rjust(2, "0") end end class StatusChange attr_reader :extra_data, :object_label, :date, :id, :status, :event_id, :origin, :order_id, :quantity, :hold_token, :is_present_on_chart, :not_present_on_chart_reason def initialize(data) @id = data['id'] @status = data['status'] @date = DateTime.iso8601(data['date']) @object_label = data['objectLabel'] @event_id = data['eventId'] @extra_data = data['extraData'] @origin = StatusChangeOrigin.new(data['origin']) @order_id = data['orderId'] @quantity = data['quantity'] @hold_token = data['holdToken'] @is_present_on_chart = data['isPresentOnChart'] @not_present_on_chart_reason = data['notPresentOnChartReason'] end end class StatusChangeOrigin attr_reader :type, :ip def initialize(data) @type = data['type'] @ip = data['ip'] end end def to_object_details(data) object_details = {} data.each do |key, value| object_details[key] = EventObjectInfo.new(value) end object_details end class SocialDistancingRuleset attr_reader :name, :number_of_disabled_seats_to_the_sides, :disable_seats_in_front_and_behind, :disable_diagonal_seats_in_front_and_behind, :number_of_disabled_aisle_seats, :max_group_size, :max_occupancy_absolute, :max_occupancy_percentage, :one_group_per_table, :fixed_group_layout, :disabled_seats, :enabled_seats, :index def initialize(name, number_of_disabled_seats_to_the_sides: 0, disable_seats_in_front_and_behind: false, disable_diagonal_seats_in_front_and_behind: false, number_of_disabled_aisle_seats: 0, max_group_size: 0, max_occupancy_absolute: 0, max_occupancy_percentage: 0, one_group_per_table: false, fixed_group_layout: false, disabled_seats: [], enabled_seats: [], index: 0) @name = name @number_of_disabled_seats_to_the_sides = number_of_disabled_seats_to_the_sides @disable_seats_in_front_and_behind = disable_seats_in_front_and_behind @disable_diagonal_seats_in_front_and_behind = disable_diagonal_seats_in_front_and_behind @number_of_disabled_aisle_seats = number_of_disabled_aisle_seats @max_group_size = max_group_size @max_occupancy_absolute = max_occupancy_absolute @max_occupancy_percentage = max_occupancy_percentage @one_group_per_table = one_group_per_table @fixed_group_layout = fixed_group_layout @disabled_seats = disabled_seats @enabled_seats = enabled_seats @index = index end def self.fixed(name, disabled_seats: [], index: 0) SocialDistancingRuleset.new(name, index: index, disabled_seats: disabled_seats, fixed_group_layout: true) end def self.rule_based(name, number_of_disabled_seats_to_the_sides: 0, disable_seats_in_front_and_behind: false, disable_diagonal_seats_in_front_and_behind: false, number_of_disabled_aisle_seats: 0, max_group_size: 0, max_occupancy_absolute: 0, max_occupancy_percentage: 0, one_group_per_table: false, disabled_seats: [], enabled_seats: [], index: 0) SocialDistancingRuleset.new(name, number_of_disabled_seats_to_the_sides: number_of_disabled_seats_to_the_sides, disable_seats_in_front_and_behind: disable_seats_in_front_and_behind, disable_diagonal_seats_in_front_and_behind: disable_diagonal_seats_in_front_and_behind, number_of_disabled_aisle_seats: number_of_disabled_aisle_seats, max_group_size: max_group_size, max_occupancy_absolute: max_occupancy_absolute, max_occupancy_percentage: max_occupancy_percentage, one_group_per_table: one_group_per_table, fixed_group_layout: false, disabled_seats: disabled_seats, enabled_seats: enabled_seats, index: index) end def == (other) name == other.name && number_of_disabled_seats_to_the_sides == other.number_of_disabled_seats_to_the_sides && disable_seats_in_front_and_behind == other.disable_seats_in_front_and_behind && disable_diagonal_seats_in_front_and_behind == other.disable_diagonal_seats_in_front_and_behind && number_of_disabled_aisle_seats == other.number_of_disabled_aisle_seats && max_group_size == other.max_group_size && max_occupancy_absolute == other.max_occupancy_absolute && max_occupancy_percentage == other.max_occupancy_percentage && one_group_per_table == other.one_group_per_table && fixed_group_layout == other.fixed_group_layout && disabled_seats == other.disabled_seats && enabled_seats == other.enabled_seats && index == other.index end end end