real_page 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ci +139 -0
- data/.gitignore +3 -0
- data/.rakeTasks +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.txt +12 -0
- data/CODEOWNERS +1 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +588 -0
- data/Rakefile +7 -0
- data/bin/console +15 -0
- data/bin/setup +7 -0
- data/config/multi_xml.rb +4 -0
- data/lib/real_page.rb +54 -0
- data/lib/real_page/attribute_parser.rb +48 -0
- data/lib/real_page/attribute_parser/base.rb +21 -0
- data/lib/real_page/attribute_parser/boolean.rb +25 -0
- data/lib/real_page/attribute_parser/date.rb +28 -0
- data/lib/real_page/attribute_parser/date_time.rb +23 -0
- data/lib/real_page/attribute_parser/decimal.rb +15 -0
- data/lib/real_page/attribute_parser/integer.rb +15 -0
- data/lib/real_page/attribute_parser/object.rb +13 -0
- data/lib/real_page/attribute_parser/string.rb +13 -0
- data/lib/real_page/document_parser.rb +6 -0
- data/lib/real_page/document_parser/base.rb +51 -0
- data/lib/real_page/document_parser/floor_plan_object.rb +30 -0
- data/lib/real_page/document_parser/guest_cards.rb +102 -0
- data/lib/real_page/document_parser/guest_cards/amenities.rb +34 -0
- data/lib/real_page/document_parser/guest_cards/prospects.rb +45 -0
- data/lib/real_page/document_parser/leases.rb +37 -0
- data/lib/real_page/document_parser/picklist.rb +38 -0
- data/lib/real_page/document_parser/rent_matrices.rb +39 -0
- data/lib/real_page/document_parser/rent_matrices/options.rb +31 -0
- data/lib/real_page/document_parser/rent_matrices/rows.rb +30 -0
- data/lib/real_page/document_parser/unit_object.rb +30 -0
- data/lib/real_page/error/bad_request.rb +18 -0
- data/lib/real_page/error/base.rb +9 -0
- data/lib/real_page/error/invalid_configuration.rb +9 -0
- data/lib/real_page/error/invalid_response.rb +9 -0
- data/lib/real_page/error/request_fault.rb +19 -0
- data/lib/real_page/error/request_fault/details.rb +17 -0
- data/lib/real_page/model/activity.rb +39 -0
- data/lib/real_page/model/address.rb +17 -0
- data/lib/real_page/model/amenity.rb +14 -0
- data/lib/real_page/model/appointment.rb +23 -0
- data/lib/real_page/model/base.rb +63 -0
- data/lib/real_page/model/base/attribute.rb +56 -0
- data/lib/real_page/model/base/attribute_store.rb +37 -0
- data/lib/real_page/model/floor_plan.rb +33 -0
- data/lib/real_page/model/follow_up.rb +34 -0
- data/lib/real_page/model/guest_card.rb +49 -0
- data/lib/real_page/model/lease.rb +36 -0
- data/lib/real_page/model/lease_action.rb +32 -0
- data/lib/real_page/model/phone_number.rb +13 -0
- data/lib/real_page/model/picklist_item.rb +10 -0
- data/lib/real_page/model/preferences.rb +25 -0
- data/lib/real_page/model/prospect.rb +35 -0
- data/lib/real_page/model/quote.rb +56 -0
- data/lib/real_page/model/rent_matrix.rb +16 -0
- data/lib/real_page/model/rent_matrix/concessions.rb +15 -0
- data/lib/real_page/model/rent_matrix/option.rb +19 -0
- data/lib/real_page/model/rent_matrix/row.rb +18 -0
- data/lib/real_page/model/screening.rb +22 -0
- data/lib/real_page/model/unit.rb +61 -0
- data/lib/real_page/model/unit_shown.rb +48 -0
- data/lib/real_page/parameter/list_criterion.rb +14 -0
- data/lib/real_page/request/base.rb +89 -0
- data/lib/real_page/request/get_floor_plan_list.rb +45 -0
- data/lib/real_page/request/get_leases_by_traffic_source.rb +59 -0
- data/lib/real_page/request/get_marketing_sources_by_property.rb +23 -0
- data/lib/real_page/request/get_rent_matrix.rb +57 -0
- data/lib/real_page/request/get_units_by_property.rb +39 -0
- data/lib/real_page/request/prospect_search.rb +50 -0
- data/lib/real_page/request_section.rb +6 -0
- data/lib/real_page/request_section/auth.rb +31 -0
- data/lib/real_page/request_section/get_rent_matrix.rb +32 -0
- data/lib/real_page/request_section/list_criteria.rb +29 -0
- data/lib/real_page/request_section/parameter.rb +31 -0
- data/lib/real_page/request_section/prospect_search_criterion.rb +24 -0
- data/lib/real_page/utils.rb +6 -0
- data/lib/real_page/utils/array_fetcher.rb +35 -0
- data/lib/real_page/utils/configuration_validator.rb +20 -0
- data/lib/real_page/utils/request_fetcher.rb +30 -0
- data/lib/real_page/utils/request_generator.rb +52 -0
- data/lib/real_page/utils/snowflake_event_tracker.rb +107 -0
- data/lib/real_page/validator.rb +6 -0
- data/lib/real_page/validator/move_in_report.rb +65 -0
- data/lib/real_page/validator/prospects_data.rb +93 -0
- data/lib/real_page/validator/request_errors.rb +97 -0
- data/lib/real_page/validator/request_fault.rb +97 -0
- data/lib/real_page/version.rb +3 -0
- data/real_page.gemspec +32 -0
- metadata +291 -0
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'pry'
|
5
|
+
require 'real_page'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start
|
data/bin/setup
ADDED
data/config/multi_xml.rb
ADDED
data/lib/real_page.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative '../config/multi_xml.rb'
|
2
|
+
|
3
|
+
require 'real_page/error/bad_request'
|
4
|
+
require 'real_page/error/invalid_configuration'
|
5
|
+
require 'real_page/error/invalid_response'
|
6
|
+
require 'real_page/error/request_fault'
|
7
|
+
|
8
|
+
require 'real_page/model/activity'
|
9
|
+
require 'real_page/model/address'
|
10
|
+
require 'real_page/model/amenity'
|
11
|
+
require 'real_page/model/appointment'
|
12
|
+
require 'real_page/model/floor_plan'
|
13
|
+
require 'real_page/model/follow_up'
|
14
|
+
require 'real_page/model/guest_card'
|
15
|
+
require 'real_page/model/lease'
|
16
|
+
require 'real_page/model/lease_action'
|
17
|
+
require 'real_page/model/phone_number'
|
18
|
+
require 'real_page/model/picklist_item'
|
19
|
+
require 'real_page/model/preferences'
|
20
|
+
require 'real_page/model/prospect'
|
21
|
+
require 'real_page/model/quote'
|
22
|
+
require 'real_page/model/rent_matrix'
|
23
|
+
require 'real_page/model/rent_matrix/concessions'
|
24
|
+
require 'real_page/model/rent_matrix/option'
|
25
|
+
require 'real_page/model/rent_matrix/row'
|
26
|
+
require 'real_page/model/screening'
|
27
|
+
require 'real_page/model/unit'
|
28
|
+
require 'real_page/model/unit_shown'
|
29
|
+
|
30
|
+
require 'real_page/parameter/list_criterion'
|
31
|
+
|
32
|
+
require 'real_page/request/get_floor_plan_list'
|
33
|
+
require 'real_page/request/get_leases_by_traffic_source'
|
34
|
+
require 'real_page/request/get_marketing_sources_by_property'
|
35
|
+
require 'real_page/request/get_rent_matrix'
|
36
|
+
require 'real_page/request/get_units_by_property'
|
37
|
+
require 'real_page/request/prospect_search'
|
38
|
+
|
39
|
+
require 'real_page/version'
|
40
|
+
|
41
|
+
module RealPage
|
42
|
+
Config = Struct.new(:web_service_url, :username, :password, :license_key, :app_name)
|
43
|
+
private_constant :Config
|
44
|
+
|
45
|
+
class << self
|
46
|
+
def configure(&block)
|
47
|
+
yield config
|
48
|
+
end
|
49
|
+
|
50
|
+
def config
|
51
|
+
@config ||= Config.new
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'real_page/attribute_parser/boolean'
|
2
|
+
require 'real_page/attribute_parser/date'
|
3
|
+
require 'real_page/attribute_parser/date_time'
|
4
|
+
require 'real_page/attribute_parser/decimal'
|
5
|
+
require 'real_page/attribute_parser/integer'
|
6
|
+
require 'real_page/attribute_parser/object'
|
7
|
+
require 'real_page/attribute_parser/string'
|
8
|
+
|
9
|
+
module RealPage
|
10
|
+
# Parse the string value from the XML response into the configured data type
|
11
|
+
class AttributeParser
|
12
|
+
# @param value [String] the response value from RealPage
|
13
|
+
# @param type [Symbol] the attribute's configured data type
|
14
|
+
def initialize(value:, type:)
|
15
|
+
@value = value
|
16
|
+
@type = type
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Object] the parsed attribute value
|
20
|
+
def parse
|
21
|
+
return unless value
|
22
|
+
case type
|
23
|
+
when :boolean
|
24
|
+
AttributeParser::Boolean.new(value).parse
|
25
|
+
when :date
|
26
|
+
AttributeParser::Date.new(value).parse
|
27
|
+
when :date_time
|
28
|
+
AttributeParser::DateTime.new(value).parse
|
29
|
+
when :decimal
|
30
|
+
AttributeParser::Decimal.new(value).parse
|
31
|
+
when :integer
|
32
|
+
AttributeParser::Integer.new(value).parse
|
33
|
+
when :object
|
34
|
+
AttributeParser::Object.new(value).parse
|
35
|
+
when :string
|
36
|
+
AttributeParser::String.new(value).parse
|
37
|
+
else
|
38
|
+
raise ArgumentError, "Invalid attribute type: #{type}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :value, :type
|
45
|
+
end
|
46
|
+
|
47
|
+
private_constant :AttributeParser
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RealPage
|
2
|
+
class AttributeParser
|
3
|
+
# Base class for attribute parsers.
|
4
|
+
class Base
|
5
|
+
# @param value [String] the response value from RealPage
|
6
|
+
def initialize(value)
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Object] the parsed attribute value
|
11
|
+
def parse
|
12
|
+
raise NotImplementedError,
|
13
|
+
"#{self.class.name} must implement #{__method__}"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module RealPage
|
4
|
+
class AttributeParser
|
5
|
+
# Parse the response value of a boolean attribute
|
6
|
+
class Boolean < Base
|
7
|
+
# Values that RealPage responds with for true
|
8
|
+
TRUE_VALUES = %w[1 true].freeze
|
9
|
+
private_constant :TRUE_VALUES
|
10
|
+
|
11
|
+
# Values that RealPage responds with for true
|
12
|
+
FALSE_VALUES = %w[0 false].freeze
|
13
|
+
private_constant :FALSE_VALUES
|
14
|
+
|
15
|
+
# @return [true|false] the parsed attribute value
|
16
|
+
# @raise [RealPage::Error::InvalidResponse] if the value doesn't parse
|
17
|
+
# into true or false
|
18
|
+
def parse
|
19
|
+
return true if TRUE_VALUES.include?(value)
|
20
|
+
return false if FALSE_VALUES.include?(value)
|
21
|
+
raise Error::InvalidResponse, "Invalid boolean response value: #{value}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module RealPage
|
4
|
+
class AttributeParser
|
5
|
+
# Parse the response value of a date attribute
|
6
|
+
class Date < Base
|
7
|
+
# RealPage responds with multiple date formats. This is one format that
|
8
|
+
# Date.parse will not parse correctly, so we need special handling
|
9
|
+
FORMAT = '%m/%d/%Y'.freeze
|
10
|
+
private_constant :FORMAT
|
11
|
+
|
12
|
+
# @return [Date] the parsed attribute value
|
13
|
+
def parse
|
14
|
+
return if value == ''
|
15
|
+
if value =~ %r[/]
|
16
|
+
::Date.strptime(value, FORMAT)
|
17
|
+
else
|
18
|
+
# RealPage sometimes returns 0001-01-01 for dates, which appears to be
|
19
|
+
# their representation of a NULL value.
|
20
|
+
date = ::Date.parse(value)
|
21
|
+
date.year == 1 ? nil : date
|
22
|
+
end
|
23
|
+
rescue ArgumentError
|
24
|
+
raise Error::InvalidResponse, "Invalid date response value: #{value}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tzinfo'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module RealPage
|
6
|
+
class AttributeParser
|
7
|
+
# Parse the response value of a date with time attribute.
|
8
|
+
class DateTime < Base
|
9
|
+
# RealPage time strings are assumed to be in Central time.
|
10
|
+
TIME_ZONE = TZInfo::Timezone.get('America/Chicago')
|
11
|
+
private_constant :TIME_ZONE
|
12
|
+
|
13
|
+
# @return [Date] the parsed attribute value
|
14
|
+
def parse
|
15
|
+
return if value == ''
|
16
|
+
date_time = ::DateTime.parse(value)
|
17
|
+
TIME_ZONE.local_to_utc(date_time) { |periods| periods.last }
|
18
|
+
rescue ArgumentError
|
19
|
+
raise Error::InvalidResponse, "Invalid date/time response value: #{value}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module RealPage
|
4
|
+
class AttributeParser
|
5
|
+
# Parse the response value of a decimal attribute
|
6
|
+
class Decimal < Base
|
7
|
+
# @return [Float] the parsed attribute value
|
8
|
+
def parse
|
9
|
+
Float(value)
|
10
|
+
rescue ArgumentError
|
11
|
+
raise Error::InvalidResponse, "Invalid decimal response value: #{value}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module RealPage
|
4
|
+
class AttributeParser
|
5
|
+
# Parse the response value of an integer attribute
|
6
|
+
class Integer < Base
|
7
|
+
# @return [Integer] the parsed attribute value
|
8
|
+
def parse
|
9
|
+
Integer(value, 10)
|
10
|
+
rescue ArgumentError
|
11
|
+
raise Error::InvalidResponse, "Invalid integer response value: #{value}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'multi_xml'
|
2
|
+
|
3
|
+
require 'real_page/validator/request_fault'
|
4
|
+
require 'real_page/document_parser'
|
5
|
+
|
6
|
+
module RealPage
|
7
|
+
module DocumentParser
|
8
|
+
# Base class for parsing RealPage responses. Subclasses must implement
|
9
|
+
# #parse_body and can optionally override #validator_classes to add more
|
10
|
+
# validation than just the default
|
11
|
+
class Base
|
12
|
+
DEFAULT_VALIDATOR_CLASSES = [Validator::RequestFault].freeze
|
13
|
+
private_constant :DEFAULT_VALIDATOR_CLASSES
|
14
|
+
|
15
|
+
# @param xml [String] the XML response from the request
|
16
|
+
# @option param request_params [Object] the request parameter
|
17
|
+
# @return [Object] the parsed object(s) from the rsesponse
|
18
|
+
# @raise [RealPage::Error::Base] if the response is invalid
|
19
|
+
|
20
|
+
def initialize(request_params: nil, request_name: nil)
|
21
|
+
@request_params = request_params
|
22
|
+
@request_name = request_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(xml)
|
26
|
+
parsed = MultiXml.parse(xml)
|
27
|
+
[*DEFAULT_VALIDATOR_CLASSES, *validator_classes].each do |klass|
|
28
|
+
klass.new(parsed, request_params, request_name).validate!
|
29
|
+
end
|
30
|
+
parse_body(parsed['s:Envelope']['s:Body'])
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :request_params, :request_name
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @param body [Hash<String, Object>] the body of the XML response parsed
|
38
|
+
# into a Hash
|
39
|
+
# @return [Object] the parsed object(s) from the rsesponse
|
40
|
+
# @raise [RealPage::Error::Base] if the response is invalid
|
41
|
+
def parse_body(body)
|
42
|
+
raise NotImplementedError,
|
43
|
+
"#{self.class.name} must implement #{__method__}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def validator_classes
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'real_page/utils/array_fetcher'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module RealPage
|
6
|
+
module DocumentParser
|
7
|
+
# Parse the GetFloorPlanList response
|
8
|
+
class FloorPlanObject < Base
|
9
|
+
private
|
10
|
+
|
11
|
+
# @param body [Hash<String, Object>] the body of the XML response parsed
|
12
|
+
# into a Hash
|
13
|
+
# @return [Array<RealPage::Model::FloorPlan>] the floor_plans contained
|
14
|
+
# in the response
|
15
|
+
# @raise [RealPage::Error::Base] if the response is invalid
|
16
|
+
def parse_body(body)
|
17
|
+
Utils::ArrayFetcher.new(
|
18
|
+
hash: floor_plans(body),
|
19
|
+
key: 'FloorPlanObject',
|
20
|
+
model: Model::FloorPlan
|
21
|
+
).fetch
|
22
|
+
end
|
23
|
+
|
24
|
+
def floor_plans(body)
|
25
|
+
response = body['getfloorplanlistResponse']
|
26
|
+
response['getfloorplanlistResult']['GetFloorPlanList']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'real_page/utils/array_fetcher'
|
2
|
+
require 'real_page/validator/prospects_data'
|
3
|
+
|
4
|
+
require_relative 'base'
|
5
|
+
|
6
|
+
module RealPage
|
7
|
+
module DocumentParser
|
8
|
+
# Parse the ProspectSearch response
|
9
|
+
class GuestCards < Base
|
10
|
+
MULTIPLE_CHILDREN = {
|
11
|
+
'Activities' => { model: Model::Activity, key: 'Activity' },
|
12
|
+
'FollowUps' => { model: Model::FollowUp, key: 'FollowUp' },
|
13
|
+
'LeaseActions' => { model: Model::LeaseAction, key: 'LeaseAction' },
|
14
|
+
'Quotes' => { model: Model::Quote, key: 'Quote' },
|
15
|
+
'Screenings' => { model: Model::Screening, key: 'Screening' },
|
16
|
+
'UnitsShown' => { model: Model::UnitShown, key: 'UnitShown' }
|
17
|
+
}
|
18
|
+
SINGLE_CHILDREN = %w[Appointment Preferences]
|
19
|
+
private_constant :MULTIPLE_CHILDREN, :SINGLE_CHILDREN
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @param body [Hash<String, Object>] the body of the XML response parsed
|
24
|
+
# into a Hash
|
25
|
+
# @return [Array<RealPage::Model::GuestCard>] the guest_cards contained
|
26
|
+
# in the response
|
27
|
+
# @raise [RealPage::Error::Base] if the response is invalid
|
28
|
+
def parse_body(body)
|
29
|
+
guest_cards(body).map do |guest_card|
|
30
|
+
attrs = guest_card.merge(children(guest_card))
|
31
|
+
attrs.delete('Amentities') # Remove the misspelled version
|
32
|
+
Model::GuestCard.new(attrs)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Hash<String,RealPage::Model] the guest_card's children that
|
37
|
+
# require more specialized parsing
|
38
|
+
def custom_children(guest_card)
|
39
|
+
{}.tap do |kids|
|
40
|
+
if guest_card['Amentities']
|
41
|
+
kids['Amenities'] = Amenities.new.parse(guest_card['Amentities'])
|
42
|
+
end
|
43
|
+
if guest_card['Prospects']
|
44
|
+
kids['Prospects'] = Prospects.new.parse(guest_card['Prospects'])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Hash] the guest_card's children, parsed into RealPage::Models
|
50
|
+
def children(guest_card)
|
51
|
+
single_children(guest_card)
|
52
|
+
.merge(multiple_children(guest_card))
|
53
|
+
.merge(custom_children(guest_card))
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Array<Hash<String, Object>>] an array of all GuestCard
|
57
|
+
# attributes
|
58
|
+
def guest_cards(body)
|
59
|
+
response = body['prospectsearchResponse']
|
60
|
+
result = response['prospectsearchResult']
|
61
|
+
prospect_search = result['ProspectSearch'] if result
|
62
|
+
return [] unless prospect_search
|
63
|
+
guest_cards = prospect_search['GuestCards']
|
64
|
+
Utils::ArrayFetcher.new(hash: guest_cards, key: 'GuestCard').fetch
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Hash<String, Array<RealPage::Model>] the guest_card's children
|
68
|
+
# that can have multiple entries
|
69
|
+
def multiple_children(guest_card)
|
70
|
+
Hash[
|
71
|
+
MULTIPLE_CHILDREN.map do |key, definition|
|
72
|
+
fetcher =
|
73
|
+
Utils::ArrayFetcher.new(definition.merge(hash: guest_card[key]))
|
74
|
+
[key, fetcher.fetch]
|
75
|
+
end
|
76
|
+
]
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [Hash<String,RealPage::Model] the guest_card's children that
|
80
|
+
# have single entries
|
81
|
+
def single_children(guest_card)
|
82
|
+
Hash[
|
83
|
+
SINGLE_CHILDREN.map do |kid|
|
84
|
+
[kid, Model.const_get(kid).new(guest_card[kid])] if guest_card[kid]
|
85
|
+
end.compact
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
def validator_classes
|
90
|
+
[Validator::ProspectsData]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# This file has a circular dependency with its sub-parsers. They file uses
|
97
|
+
# the others to help parse the inner objects of the XML, and that file's class
|
98
|
+
# definition is nested within this class.
|
99
|
+
#
|
100
|
+
# Having the require at the bottom of the file keeps the class loader happy
|
101
|
+
require_relative 'guest_cards/prospects'
|
102
|
+
require_relative 'guest_cards/amenities'
|