real_page 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.ci +139 -0
  3. data/.gitignore +3 -0
  4. data/.rakeTasks +7 -0
  5. data/.rspec +3 -0
  6. data/CHANGELOG.txt +12 -0
  7. data/CODEOWNERS +1 -0
  8. data/CODE_OF_CONDUCT.md +13 -0
  9. data/Gemfile +6 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +588 -0
  12. data/Rakefile +7 -0
  13. data/bin/console +15 -0
  14. data/bin/setup +7 -0
  15. data/config/multi_xml.rb +4 -0
  16. data/lib/real_page.rb +54 -0
  17. data/lib/real_page/attribute_parser.rb +48 -0
  18. data/lib/real_page/attribute_parser/base.rb +21 -0
  19. data/lib/real_page/attribute_parser/boolean.rb +25 -0
  20. data/lib/real_page/attribute_parser/date.rb +28 -0
  21. data/lib/real_page/attribute_parser/date_time.rb +23 -0
  22. data/lib/real_page/attribute_parser/decimal.rb +15 -0
  23. data/lib/real_page/attribute_parser/integer.rb +15 -0
  24. data/lib/real_page/attribute_parser/object.rb +13 -0
  25. data/lib/real_page/attribute_parser/string.rb +13 -0
  26. data/lib/real_page/document_parser.rb +6 -0
  27. data/lib/real_page/document_parser/base.rb +51 -0
  28. data/lib/real_page/document_parser/floor_plan_object.rb +30 -0
  29. data/lib/real_page/document_parser/guest_cards.rb +102 -0
  30. data/lib/real_page/document_parser/guest_cards/amenities.rb +34 -0
  31. data/lib/real_page/document_parser/guest_cards/prospects.rb +45 -0
  32. data/lib/real_page/document_parser/leases.rb +37 -0
  33. data/lib/real_page/document_parser/picklist.rb +38 -0
  34. data/lib/real_page/document_parser/rent_matrices.rb +39 -0
  35. data/lib/real_page/document_parser/rent_matrices/options.rb +31 -0
  36. data/lib/real_page/document_parser/rent_matrices/rows.rb +30 -0
  37. data/lib/real_page/document_parser/unit_object.rb +30 -0
  38. data/lib/real_page/error/bad_request.rb +18 -0
  39. data/lib/real_page/error/base.rb +9 -0
  40. data/lib/real_page/error/invalid_configuration.rb +9 -0
  41. data/lib/real_page/error/invalid_response.rb +9 -0
  42. data/lib/real_page/error/request_fault.rb +19 -0
  43. data/lib/real_page/error/request_fault/details.rb +17 -0
  44. data/lib/real_page/model/activity.rb +39 -0
  45. data/lib/real_page/model/address.rb +17 -0
  46. data/lib/real_page/model/amenity.rb +14 -0
  47. data/lib/real_page/model/appointment.rb +23 -0
  48. data/lib/real_page/model/base.rb +63 -0
  49. data/lib/real_page/model/base/attribute.rb +56 -0
  50. data/lib/real_page/model/base/attribute_store.rb +37 -0
  51. data/lib/real_page/model/floor_plan.rb +33 -0
  52. data/lib/real_page/model/follow_up.rb +34 -0
  53. data/lib/real_page/model/guest_card.rb +49 -0
  54. data/lib/real_page/model/lease.rb +36 -0
  55. data/lib/real_page/model/lease_action.rb +32 -0
  56. data/lib/real_page/model/phone_number.rb +13 -0
  57. data/lib/real_page/model/picklist_item.rb +10 -0
  58. data/lib/real_page/model/preferences.rb +25 -0
  59. data/lib/real_page/model/prospect.rb +35 -0
  60. data/lib/real_page/model/quote.rb +56 -0
  61. data/lib/real_page/model/rent_matrix.rb +16 -0
  62. data/lib/real_page/model/rent_matrix/concessions.rb +15 -0
  63. data/lib/real_page/model/rent_matrix/option.rb +19 -0
  64. data/lib/real_page/model/rent_matrix/row.rb +18 -0
  65. data/lib/real_page/model/screening.rb +22 -0
  66. data/lib/real_page/model/unit.rb +61 -0
  67. data/lib/real_page/model/unit_shown.rb +48 -0
  68. data/lib/real_page/parameter/list_criterion.rb +14 -0
  69. data/lib/real_page/request/base.rb +89 -0
  70. data/lib/real_page/request/get_floor_plan_list.rb +45 -0
  71. data/lib/real_page/request/get_leases_by_traffic_source.rb +59 -0
  72. data/lib/real_page/request/get_marketing_sources_by_property.rb +23 -0
  73. data/lib/real_page/request/get_rent_matrix.rb +57 -0
  74. data/lib/real_page/request/get_units_by_property.rb +39 -0
  75. data/lib/real_page/request/prospect_search.rb +50 -0
  76. data/lib/real_page/request_section.rb +6 -0
  77. data/lib/real_page/request_section/auth.rb +31 -0
  78. data/lib/real_page/request_section/get_rent_matrix.rb +32 -0
  79. data/lib/real_page/request_section/list_criteria.rb +29 -0
  80. data/lib/real_page/request_section/parameter.rb +31 -0
  81. data/lib/real_page/request_section/prospect_search_criterion.rb +24 -0
  82. data/lib/real_page/utils.rb +6 -0
  83. data/lib/real_page/utils/array_fetcher.rb +35 -0
  84. data/lib/real_page/utils/configuration_validator.rb +20 -0
  85. data/lib/real_page/utils/request_fetcher.rb +30 -0
  86. data/lib/real_page/utils/request_generator.rb +52 -0
  87. data/lib/real_page/utils/snowflake_event_tracker.rb +107 -0
  88. data/lib/real_page/validator.rb +6 -0
  89. data/lib/real_page/validator/move_in_report.rb +65 -0
  90. data/lib/real_page/validator/prospects_data.rb +93 -0
  91. data/lib/real_page/validator/request_errors.rb +97 -0
  92. data/lib/real_page/validator/request_fault.rb +97 -0
  93. data/lib/real_page/version.rb +3 -0
  94. data/real_page.gemspec +32 -0
  95. metadata +291 -0
@@ -0,0 +1,34 @@
1
+ require 'real_page/utils/array_fetcher'
2
+
3
+ require_relative '../guest_cards'
4
+
5
+ module RealPage
6
+ module DocumentParser
7
+ class GuestCards
8
+ # Parse the Amenities from a GuestCards response. RealPage spells
9
+ # everything "amentities", so we also correct for that.
10
+ class Amenities < Base
11
+ # @param amenities_hash [Array<Hash<String, Object>>] an 'Amentities'
12
+ # entry of the XML response parsed into a Hash
13
+ # @return [Array<RealPage::Model::Amenity>] the amenities contained
14
+ # in this amenities_hash
15
+ # @raise [RealPage::Error::Base] if the response is invalid
16
+ def parse(amenities_hash)
17
+ amenities(amenities_hash).map do |amenity|
18
+ attrs = amenity.dup
19
+ # RealPage spells AmenityID wrong
20
+ attrs['AmenityID'] = attrs.delete('AmentityID')
21
+ Model::Amenity.new(attrs)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def amenities(amenities_hash)
28
+ #R RealPage spells the Amenity tag wrong
29
+ Utils::ArrayFetcher.new(hash: amenities_hash, key: 'Amentity').fetch
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,45 @@
1
+ require 'real_page/utils/array_fetcher'
2
+
3
+ require_relative '../guest_cards'
4
+
5
+ module RealPage
6
+ module DocumentParser
7
+ class GuestCards
8
+ # Parse the Prospects from a GuestCards response
9
+ class Prospects < Base
10
+ # @param prospects_hash [Array<Hash<String, Object>>] a 'Prospects'
11
+ # entry of the XML response parsed into a Hash
12
+ # @return [Array<RealPage::Model::Prospect>] the prospects contained
13
+ # in this prospects_hash
14
+ # @raise [RealPage::Error::Base] if the response is invalid
15
+ def parse(prospects_hash)
16
+ prospects(prospects_hash).map do |prospect|
17
+ attrs = prospect.merge(
18
+ 'PhoneNumbers' => phone_numbers(prospect['Numbers'])
19
+ )
20
+ if prospect['Address']
21
+ attrs['Address'] = Model::Address.new(prospect['Address'])
22
+ end
23
+ # RealPage is inconsistent about Number vs PhoneNumber
24
+ attrs.delete('Numbers')
25
+ Model::Prospect.new(attrs)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def phone_numbers(phone_numbers_hash)
32
+ Utils::ArrayFetcher.new(
33
+ hash: phone_numbers_hash,
34
+ key: 'PhoneNumber',
35
+ model: Model::PhoneNumber
36
+ ).fetch
37
+ end
38
+
39
+ def prospects(prospects_hash)
40
+ Utils::ArrayFetcher.new(hash: prospects_hash, key: 'Prospect').fetch
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'real_page/utils/array_fetcher'
2
+ require 'real_page/validator/request_errors'
3
+ require 'real_page/validator/move_in_report'
4
+
5
+ require_relative 'base'
6
+
7
+ module RealPage
8
+ module DocumentParser
9
+ # Parse the GetLeasesByTrafficSource response
10
+ class Leases < Base
11
+ private
12
+
13
+ # @param body [Hash<String, Object>] the body of the XML response parsed
14
+ # into a Hash
15
+ # @return [Array<RealPage::Model::Lease>] the leases contained in the
16
+ # response
17
+ # @raise [RealPage::Error::Base] if the response is invalid
18
+ def parse_body(body)
19
+ Utils::ArrayFetcher.new(
20
+ hash: leases(body),
21
+ key: 'lease',
22
+ model: Model::Lease
23
+ ).fetch
24
+ end
25
+
26
+ def leases(body)
27
+ response = body['getleasesbytrafficsourceResponse']
28
+ result = response['getleasesbytrafficsourceResult']
29
+ result['getleasesbytrafficsourceresponse']['leases']
30
+ end
31
+
32
+ def validator_classes
33
+ [Validator::RequestErrors, Validator::MoveInReport]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ require 'real_page/utils/array_fetcher'
2
+
3
+ require_relative 'base'
4
+
5
+ module RealPage
6
+ module DocumentParser
7
+ # Parse a Picklist response
8
+ class Picklist < Base
9
+ # @param soap_action [String] the action requested
10
+ def initialize(soap_action)
11
+ @soap_action = soap_action
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :soap_action
17
+
18
+ # @param body [Hash<String, Object>] the body of the XML response parsed
19
+ # into a Hash
20
+ # @return [Array<RealPage::Model::PicklistItem>] the pick list items
21
+ # parsed from the response
22
+ # @raise [RealPage::Error::Base] if the response is invalid
23
+ def parse_body(body)
24
+ Utils::ArrayFetcher.new(
25
+ hash: items(body),
26
+ key: 'PicklistItem',
27
+ model: Model::PicklistItem
28
+ ).fetch
29
+ end
30
+
31
+ def items(body)
32
+ response_key = "#{soap_action.downcase}Response"
33
+ result_key = "#{soap_action.downcase}Result"
34
+ body[response_key][result_key][soap_action]['Contents']
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ require 'real_page/utils/array_fetcher'
2
+
3
+ require_relative 'base'
4
+
5
+ module RealPage
6
+ module DocumentParser
7
+ # Parse the GetRentMatrix response
8
+ class RentMatrices < 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::RentMatrix>] the rent matrices contained
14
+ # in the response
15
+ # @raise [RealPage::Error::Base] if the response is invalid
16
+ def parse_body(body)
17
+ row_parser = Rows.new
18
+ matrices(body).map do |matrix|
19
+ rows = row_parser.parse(matrix['Rows'])
20
+ attrs = matrix.merge('Rows' => rows)
21
+ Model::RentMatrix.new(attrs)
22
+ end
23
+ end
24
+
25
+ def matrices(body)
26
+ result = body['getrentmatrixResponse']['getrentmatrixResult']
27
+ matrices = result['GetRentMatrix']['RentMatrices']
28
+ Utils::ArrayFetcher.new(hash: matrices, key: 'RentMatrix').fetch
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ # This file has a circular dependency with rent_matrices/row. This file uses
35
+ # the other to help parse the inner rows of the XML and that file's class
36
+ # definition is nested within this class.
37
+ #
38
+ # Having the require at the bottom of the file keeps the class loader happy
39
+ require_relative 'rent_matrices/rows'
@@ -0,0 +1,31 @@
1
+ require_relative '../rent_matrices'
2
+
3
+ module RealPage
4
+ module DocumentParser
5
+ class RentMatrices
6
+ # Parse the options from a GetRentMatrix response
7
+ class Options < Base
8
+ # @param options_array [Array<Hash>] a 'Options' entry of the XML
9
+ # response parsed into an array
10
+ # @return [Array<RealPage::Model::RentMatrix::Option>] the options
11
+ # contained in this row
12
+ # @raise [RealPage::Error::Base] if the response is invalid
13
+ def parse(options_array)
14
+ options_array.map do |option_hash|
15
+ options = option_hash['Option']
16
+ options = [options] unless options.is_a?(Array)
17
+ options.map do |option|
18
+ concessions =
19
+ Model::RentMatrix::Concessions.new(option['Concessions'])
20
+ attrs = option.merge(
21
+ 'Concessions' => concessions,
22
+ 'LeaseStartDate' => option_hash['LeaseStartDate']
23
+ )
24
+ Model::RentMatrix::Option.new(attrs)
25
+ end
26
+ end.flatten
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ require 'real_page/utils/array_fetcher'
2
+
3
+ require_relative '../rent_matrices'
4
+ require_relative 'options'
5
+
6
+ module RealPage
7
+ module DocumentParser
8
+ class RentMatrices
9
+ # Parse the rows from a GetRentMatrix response
10
+ class Rows < Base
11
+ # @param rows_hash [Hash<String, Object>] a 'Rows' entry of the XML
12
+ # response parsed into a Hash
13
+ # @return [Array<RealPage::Model::RentMatrix::Row>] the rows contained
14
+ # in this rows_hash
15
+ # @raise [RealPage::Error::Base] if the response is invalid
16
+ def parse(rows_hash)
17
+ rows = Utils::ArrayFetcher.new(hash: rows_hash, key: 'Row').fetch
18
+ options_parser = Options.new
19
+ rows.map do |row|
20
+ options_hash =
21
+ Utils::ArrayFetcher.new(hash: row, key: 'Options').fetch
22
+ options = options_parser.parse(options_hash)
23
+ attrs = row.merge('Options' => options)
24
+ Model::RentMatrix::Row.new(attrs)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ 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 GetUnitsByProperty response
8
+ class UnitObject < 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::Unit>] the units contained in the
14
+ # response
15
+ # @raise [RealPage::Error::Base] if the response is invalid
16
+ def parse_body(body)
17
+ Utils::ArrayFetcher.new(
18
+ hash: units(body),
19
+ key: 'UnitObject',
20
+ model: Model::Unit
21
+ ).fetch
22
+ end
23
+
24
+ def units(body)
25
+ result = body['getunitsbypropertyResponse']['getunitsbypropertyResult']
26
+ result['GetUnitsByProperty']
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'base'
2
+
3
+ module RealPage
4
+ module Error
5
+ # Raised when a RealPage request has an error node in the contents. This is
6
+ # generally the case when one of the parameters in a section other than the
7
+ # auth section is invalid.
8
+ class BadRequest < Base
9
+ attr_reader :errors
10
+
11
+ # @param errors [Object] object must respond to message
12
+ def initialize(errors)
13
+ super(errors.map(&:message).join('; '))
14
+ @errors = errors
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module RealPage
2
+ module Error
3
+ # A base class for all errors that originate from this gem
4
+ class Base < StandardError
5
+ end
6
+
7
+ private_constant :Base
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'base'
2
+
3
+ module RealPage
4
+ module Error
5
+ # Raised when RealPage is not properly configured
6
+ class InvalidConfiguration < Base
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'base'
2
+
3
+ module RealPage
4
+ module Error
5
+ # Raised when we cannot parse the response
6
+ class InvalidResponse < Base
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'base'
2
+ require_relative 'request_fault/details'
3
+
4
+ module RealPage
5
+ module Error
6
+ # Raised when a RealPage request has a fault node, which general appears
7
+ # when there is an issue with the auth section in the request (e.g.
8
+ # invalid password)
9
+ class RequestFault < Base
10
+ attr_reader :fault_code, :details
11
+
12
+ def initialize(message, fault_code, details = nil)
13
+ super(message)
14
+ @fault_code = fault_code
15
+ @details = details
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ require_relative '../base'
2
+
3
+ module RealPage
4
+ module Error
5
+ class RequestFault < Base
6
+ class Details
7
+ attr_reader :custom_message, :exception_message, :log_id
8
+
9
+ def initialize(custom_message:, exception_message:, log_id:)
10
+ @custom_message = custom_message
11
+ @exception_message = exception_message
12
+ @log_id = log_id
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'base'
2
+
3
+ module RealPage
4
+ module Model
5
+ # Object to encapsulate an Activity from a RealPage response.
6
+ class Activity < Base
7
+ boolean_attrs *%i[
8
+ system
9
+ ]
10
+
11
+ date_attrs *%i[
12
+ create_date
13
+ ]
14
+
15
+ integer_attrs *%i[
16
+ agent_id
17
+ max_create_date_time
18
+ ]
19
+
20
+ string_attrs *%i[
21
+ agent_name
22
+ date
23
+ edit_type_name
24
+ guest_card_journal_edit_type_id
25
+ guest_card_journal_type_id
26
+ id
27
+ logged_by_name
28
+ loss_reason_cd
29
+ name
30
+ notes
31
+ result
32
+ result_cd
33
+ status
34
+ status_change_reason
35
+ time
36
+ ]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'base'
2
+
3
+ module RealPage
4
+ module Model
5
+ # Object to encapsulate a Address from a RealPage response.
6
+ class Address < Base
7
+ string_attrs *%i[
8
+ city
9
+ country
10
+ line1
11
+ line2
12
+ state
13
+ zip
14
+ ]
15
+ end
16
+ end
17
+ end