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
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
require 'real_page/utils'
|
4
|
+
require 'real_page/utils/configuration_validator'
|
5
|
+
|
6
|
+
module RealPage
|
7
|
+
module Utils
|
8
|
+
# Send a SOAP request to RealPage
|
9
|
+
class RequestFetcher
|
10
|
+
# @param generator [RequestGenerator] an instance of a RequestGenerator,
|
11
|
+
# which responds to #generate(pmc_id, site_id).
|
12
|
+
def initialize(generator:)
|
13
|
+
@generator = generator
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [String] the XML response from RealPage
|
17
|
+
def fetch
|
18
|
+
ConfigurationValidator.new.validate!
|
19
|
+
Faraday.new.post(RealPage.config.web_service_url) do |request|
|
20
|
+
request.body = generator.body
|
21
|
+
request.headers = generator.headers
|
22
|
+
end.body
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :generator
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
require 'real_page/utils'
|
4
|
+
|
5
|
+
module RealPage
|
6
|
+
module Utils
|
7
|
+
# Generate a SOAP request for a specific action and sections
|
8
|
+
class RequestGenerator
|
9
|
+
ENVELOPE = {
|
10
|
+
'xmlns:soapenv' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
11
|
+
'xmlns:tem' => 'http://tempuri.org/'
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# @param soap_action [String] the action to request from RealPage.
|
15
|
+
# @param sections [Array<RequestSection>] the section generators that will
|
16
|
+
# be used to generate the body of the XML request
|
17
|
+
def initialize(soap_action, sections)
|
18
|
+
@soap_action = soap_action
|
19
|
+
@sections = sections
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [String] the XML request for the specified action and sections
|
23
|
+
def body
|
24
|
+
Nokogiri::XML::Builder.new do |xml_builder|
|
25
|
+
xml_builder.Envelope(ENVELOPE) do
|
26
|
+
namespace = xml_builder.parent.namespace_definitions.first
|
27
|
+
xml_builder.parent.namespace = namespace
|
28
|
+
xml_builder['soapenv'].Header
|
29
|
+
xml_builder['soapenv'].Body do
|
30
|
+
xml_builder['tem'].send(soap_action.downcase) do
|
31
|
+
sections.each do |section|
|
32
|
+
section.generate(xml_builder['tem'])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end.to_xml
|
38
|
+
end
|
39
|
+
|
40
|
+
def headers
|
41
|
+
{
|
42
|
+
'Content-Type' => 'text/xml; charset=utf-8',
|
43
|
+
'SOAPAction' => "http://tempuri.org/IRPXService/#{soap_action.downcase}"
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_reader :soap_action, :sections
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'event_tracker'
|
3
|
+
require 'real_page/utils'
|
4
|
+
|
5
|
+
module RealPage
|
6
|
+
module Utils
|
7
|
+
class SnowflakeEventTracker
|
8
|
+
IMPORT_PMS_RESIDENT_EVENT = 'import_pms_resident'
|
9
|
+
IMPORT_PMS_PROSPECT_EVENT = 'import_pms_prospect'
|
10
|
+
|
11
|
+
def self.track_pms_resident_event(
|
12
|
+
remote_lease_id: nil,
|
13
|
+
resident_type:,
|
14
|
+
request_params:,
|
15
|
+
move_in_date: nil,
|
16
|
+
lease_to: nil,
|
17
|
+
lease_from: nil,
|
18
|
+
first_name_present: false,
|
19
|
+
last_name_present: false,
|
20
|
+
email_present: false,
|
21
|
+
phones_count:,
|
22
|
+
error: nil
|
23
|
+
)
|
24
|
+
EventTracker.track_process_events(name: IMPORT_PMS_RESIDENT_EVENT) do |events|
|
25
|
+
events.add_imported_event(
|
26
|
+
EventTracker::ResourceFactory.build_pms_resident(
|
27
|
+
billing_import: EventTracker::BillingImportFactory.build_billing_import(
|
28
|
+
property_id: request_params[:billing_config].property_id,
|
29
|
+
billing_config_id: request_params[:billing_config].id,
|
30
|
+
remote_id: request_params[:site_id],
|
31
|
+
pms_type: 'real_page',
|
32
|
+
import_id: request_params[:import_id],
|
33
|
+
pmc_id: request_params[:pmc_id],
|
34
|
+
service: RealPage.config.app_name
|
35
|
+
),
|
36
|
+
remote_lease_id: remote_lease_id,
|
37
|
+
import_resident_id: import_resident_id(request_params[:import_id]),
|
38
|
+
resident_type: resident_type,
|
39
|
+
api_name: 'GetLeasesByTrafficSource',
|
40
|
+
request_params: EventTracker::ResourceFactory::PmsResident.build_request_params(
|
41
|
+
start_date: request_params[:start_date],
|
42
|
+
end_date: request_params[:end_date],
|
43
|
+
prospect_id: request_params[:prospect_id],
|
44
|
+
pmc_id: request_params[:pmc_id],
|
45
|
+
remote_id: request_params[:site_id],
|
46
|
+
traffic_source_id: request_params[:traffic_source_id]
|
47
|
+
),
|
48
|
+
move_in_date: move_in_date,
|
49
|
+
lease_to: lease_to,
|
50
|
+
lease_from: lease_from,
|
51
|
+
first_name_present: first_name_present,
|
52
|
+
last_name_present: last_name_present,
|
53
|
+
email_present: email_present,
|
54
|
+
phones_count: phones_count,
|
55
|
+
error: error
|
56
|
+
)
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.track_pms_prospect_event(
|
62
|
+
remote_lease_id: nil,
|
63
|
+
resident_type:,
|
64
|
+
request_params:,
|
65
|
+
contact_date: nil,
|
66
|
+
contact_source: nil,
|
67
|
+
remote_prospect_id: nil,
|
68
|
+
error: nil
|
69
|
+
)
|
70
|
+
EventTracker.track_process_events(name: IMPORT_PMS_PROSPECT_EVENT) do |events|
|
71
|
+
events.add_imported_event(
|
72
|
+
EventTracker::ResourceFactory.build_pms_prospect(
|
73
|
+
billing_import: EventTracker::BillingImportFactory.build_billing_import(
|
74
|
+
property_id: request_params[:billing_config].property_id,
|
75
|
+
billing_config_id: request_params[:billing_config].id,
|
76
|
+
remote_id: request_params[:site_id],
|
77
|
+
pms_type: 'real_page',
|
78
|
+
import_id: request_params[:import_id],
|
79
|
+
pmc_id: request_params[:pmc_id],
|
80
|
+
service: RealPage.config.app_name
|
81
|
+
),
|
82
|
+
remote_lease_id: remote_lease_id,
|
83
|
+
import_resident_id: import_resident_id(request_params[:import_id]),
|
84
|
+
resident_type: resident_type,
|
85
|
+
api_name: 'ProspectSearch',
|
86
|
+
request_params: EventTracker::ResourceFactory::PmsProspect.build_request_params(
|
87
|
+
pmc_id: request_params[:pmc_id],
|
88
|
+
remote_id: request_params[:site_id],
|
89
|
+
prospect_id: request_params[:guest_card_id]
|
90
|
+
),
|
91
|
+
contact_date: contact_date,
|
92
|
+
contact_source: contact_source,
|
93
|
+
remote_prospect_id: remote_prospect_id,
|
94
|
+
error: error
|
95
|
+
)
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def self.import_resident_id(import_id)
|
103
|
+
"#{import_id}-#{SecureRandom.alphanumeric(15)}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
2
|
+
|
3
|
+
require 'real_page/validator'
|
4
|
+
require 'real_page/utils/snowflake_event_tracker'
|
5
|
+
|
6
|
+
module RealPage
|
7
|
+
module Validator
|
8
|
+
# Send parased response's move-in report data to Snowflake via event tracker
|
9
|
+
|
10
|
+
class MoveInReport
|
11
|
+
def initialize(response, request_params, request_name)
|
12
|
+
@response = response
|
13
|
+
@request_params = request_params
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate!
|
17
|
+
return if leases.blank?
|
18
|
+
send_successful_response_data_to_snowflake
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :response, :request_params
|
24
|
+
|
25
|
+
def send_successful_response_data_to_snowflake
|
26
|
+
leases.each do |lease|
|
27
|
+
Utils::SnowflakeEventTracker.track_pms_resident_event(
|
28
|
+
remote_lease_id: lease['leaseid'],
|
29
|
+
resident_type: 'PRIMARY',
|
30
|
+
request_params: request_params,
|
31
|
+
move_in_date: DateTime.strptime(lease['moveindate'], '%m/%d/%y').to_time,
|
32
|
+
lease_to: DateTime.strptime(lease['leaseenddate'], '%m/%d/%y').to_time,
|
33
|
+
lease_from: DateTime.strptime(lease['leasebegindate'], '%m/%d/%y').to_time,
|
34
|
+
first_name_present: !lease['firstname'].blank?,
|
35
|
+
last_name_present: !lease['lastname'].blank?,
|
36
|
+
email_present: !lease['email'].blank?,
|
37
|
+
phones_count: phones_count(lease)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def leases
|
43
|
+
body = response['s:Envelope']['s:Body']
|
44
|
+
response_key = body.keys.detect { |key| key !~ /^xmlns/ }
|
45
|
+
contents_response = body.fetch(response_key)
|
46
|
+
result_key = contents_response.keys.detect { |key| key !~ /^xmlns/ }
|
47
|
+
contents_result = contents_response.fetch(result_key)
|
48
|
+
result = contents_result.values.first
|
49
|
+
leases_hash = result.dig('leases', 'lease')
|
50
|
+
return [] if leases_hash.nil?
|
51
|
+
return [leases_hash] unless leases_hash.is_a?(Array)
|
52
|
+
leases_hash
|
53
|
+
end
|
54
|
+
|
55
|
+
def phones_count(lease)
|
56
|
+
count = 0
|
57
|
+
phone_keys = lease.keys.select { |key| key.include?('phone') && !key.include?('phoneext') }
|
58
|
+
phone_keys.each do |phone_key|
|
59
|
+
count +=1 unless lease[phone_key].blank?
|
60
|
+
end
|
61
|
+
count
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
2
|
+
|
3
|
+
require 'real_page/validator'
|
4
|
+
require 'real_page/utils/snowflake_event_tracker'
|
5
|
+
|
6
|
+
module RealPage
|
7
|
+
module Validator
|
8
|
+
# Sends parased response's roommate and prospect data to Snowflake via event tracker
|
9
|
+
|
10
|
+
class ProspectsData
|
11
|
+
def initialize(response, request_params, request_name)
|
12
|
+
@response = response
|
13
|
+
@request_params = request_params
|
14
|
+
@guest_cards = guest_cards
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate!
|
18
|
+
return if guest_cards.blank?
|
19
|
+
send_data_to_snowflake
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :response, :request_params, :guest_cards
|
25
|
+
|
26
|
+
def send_data_to_snowflake
|
27
|
+
guest_cards.each do |guest_card|
|
28
|
+
prospects_of_current_guest_card = prospects(guest_card)
|
29
|
+
send_roommates_data_to_snowflake(prospects_of_current_guest_card)
|
30
|
+
send_prospects_data_to_snowflake(prospects_of_current_guest_card, guest_card)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_roommates_data_to_snowflake(prospects)
|
35
|
+
prospects.each do |prospect|
|
36
|
+
Utils::SnowflakeEventTracker.track_pms_resident_event(
|
37
|
+
resident_type: 'ROOMMATE',
|
38
|
+
request_params: request_params,
|
39
|
+
first_name_present: !prospect['FirstName'].blank?,
|
40
|
+
last_name_present: !prospect['LastName'].blank?,
|
41
|
+
email_present: !prospect['Email'].blank?,
|
42
|
+
phones_count: phones_count(prospect)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_prospects_data_to_snowflake(prospects, guest_card)
|
48
|
+
prospects.each do |prospect|
|
49
|
+
Utils::SnowflakeEventTracker.track_pms_prospect_event(
|
50
|
+
resident_type: 'ROOMMATE',
|
51
|
+
request_params: request_params,
|
52
|
+
contact_date: DateTime.parse(guest_card['DateContact']).to_time,
|
53
|
+
contact_source: guest_card['PrimaryLeadSource'],
|
54
|
+
remote_prospect_id: prospect['IdNumber']
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def guest_cards
|
60
|
+
guest_cards_hash = parsed_response.dig('GuestCards', 'GuestCard')
|
61
|
+
return [] if guest_cards_hash.nil?
|
62
|
+
return [guest_cards_hash] unless guest_cards_hash.is_a?(Array)
|
63
|
+
guest_cards_hash
|
64
|
+
end
|
65
|
+
|
66
|
+
def prospects(guest_card)
|
67
|
+
prospects_hash = guest_card.dig('Prospects', 'Prospect')
|
68
|
+
return [] if prospects_hash.nil?
|
69
|
+
return [prospects_hash] unless prospects_hash.is_a?(Array)
|
70
|
+
prospects_hash
|
71
|
+
end
|
72
|
+
|
73
|
+
def parsed_response
|
74
|
+
body = response['s:Envelope']['s:Body']
|
75
|
+
response_key = body.keys.detect { |key| key !~ /^xmlns/ }
|
76
|
+
contents_response = body.fetch(response_key)
|
77
|
+
result_key = contents_response.keys.detect { |key| key !~ /^xmlns/ }
|
78
|
+
contents_result = contents_response.fetch(result_key)
|
79
|
+
result = contents_result.values.first
|
80
|
+
end
|
81
|
+
|
82
|
+
def phones_count(prospect)
|
83
|
+
phone_numbers_hash = prospect.dig('Numbers', 'PhoneNumber')
|
84
|
+
return 0 if phone_numbers_hash.blank?
|
85
|
+
if !phone_numbers_hash.is_a?(Array)
|
86
|
+
return 0 if phone_numbers_hash['Number'].blank?
|
87
|
+
return 1
|
88
|
+
end
|
89
|
+
phone_numbers_hash.select { |phone_number| !phone_number['Number'].blank? }.length
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
2
|
+
|
3
|
+
require 'real_page/utils/array_fetcher'
|
4
|
+
require 'real_page/utils/snowflake_event_tracker'
|
5
|
+
|
6
|
+
module RealPage
|
7
|
+
module Validator
|
8
|
+
# Ensure there are no errors in the wrapped contents of the body.
|
9
|
+
#
|
10
|
+
# This validator works on responses that have the following format:
|
11
|
+
#
|
12
|
+
# <s:Envelope>
|
13
|
+
# <s:Body>
|
14
|
+
# <actionnameResponse>
|
15
|
+
# <actionnameResult>
|
16
|
+
# <actionnameresponse>
|
17
|
+
# <success>false</success>
|
18
|
+
# <errorcount>1</errorcount>
|
19
|
+
# <errors>
|
20
|
+
# <error>
|
21
|
+
# <severity>Critical</severity>
|
22
|
+
# <errornumber>1</errornumber>
|
23
|
+
# <errormessage>something went wrong</errormessage>
|
24
|
+
# <internalerrormessage/>
|
25
|
+
# </error>
|
26
|
+
# </errors>
|
27
|
+
# </actionnameresponse>
|
28
|
+
# </actionnameResult>
|
29
|
+
# </actionnameResponse>
|
30
|
+
# </s:Body>
|
31
|
+
# </s:Envelope>
|
32
|
+
class RequestErrors
|
33
|
+
# Ensure the concatenated error message does not exceed Snowflake error column max
|
34
|
+
# character length. The error column data type is VARCHAR(16777216)
|
35
|
+
# 16777216 bytes / 4 bytes per character = 4194304 characters
|
36
|
+
MAX_ERROR_LENGTH = 4194304
|
37
|
+
private_constant :MAX_ERROR_LENGTH
|
38
|
+
|
39
|
+
# @param response [Hash<String, Object>] the XML response parsed into a
|
40
|
+
# Hash
|
41
|
+
def initialize(response, request_params, request_name)
|
42
|
+
@response = response
|
43
|
+
@request_params = request_params
|
44
|
+
end
|
45
|
+
|
46
|
+
# @raise [RealPage::Error::RequestFault] if the response has an error
|
47
|
+
# node in the contents
|
48
|
+
def validate!
|
49
|
+
return unless error?
|
50
|
+
send_request_error_to_snowflake
|
51
|
+
raise RealPage::Error::BadRequest.new(errors)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
attr_reader :response, :request_params
|
57
|
+
|
58
|
+
def contents
|
59
|
+
body = response['s:Envelope']['s:Body']
|
60
|
+
response_key = body.keys.detect { |key| key !~ /^xmlns/ }
|
61
|
+
contents_response = body[response_key]
|
62
|
+
result_key = contents_response.keys.detect { |key| key !~ /^xmlns/ }
|
63
|
+
contents_result = contents_response[result_key]
|
64
|
+
contents_result.values.first
|
65
|
+
end
|
66
|
+
|
67
|
+
def error?
|
68
|
+
contents['success'] == 'false'
|
69
|
+
end
|
70
|
+
|
71
|
+
def errors
|
72
|
+
errors = contents['errors']
|
73
|
+
errors_array = Utils::ArrayFetcher.new(hash: errors, key: 'error').fetch
|
74
|
+
errors_array.map do |error|
|
75
|
+
Struct.new(:message, :severity, :internal_message).new(
|
76
|
+
error['errormessage'],
|
77
|
+
error['severity'],
|
78
|
+
error['internalerrormessage']
|
79
|
+
)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def send_request_error_to_snowflake
|
84
|
+
Utils::SnowflakeEventTracker.track_pms_resident_event(
|
85
|
+
resident_type: 'PRIMARY',
|
86
|
+
request_params: request_params,
|
87
|
+
phones_count: 0,
|
88
|
+
error: error_messages
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def error_messages
|
93
|
+
errors.map(&:message).join(' ').slice(0, MAX_ERROR_LENGTH)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|