real_page 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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