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.
- 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
|