yardi 4.0.8 → 4.11.2

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 (41) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +6 -19
  4. data/.rubocop_todo.yml +264 -0
  5. data/Gemfile +11 -0
  6. data/README.md +50 -28
  7. data/bin/console +0 -0
  8. data/lib/yardi/document_parser/base.rb +35 -5
  9. data/lib/yardi/document_parser/guest_card_import_response_object.rb +1 -1
  10. data/lib/yardi/document_parser/properties.rb +39 -0
  11. data/lib/yardi/document_parser/prospects.rb +23 -5
  12. data/lib/yardi/document_parser/residents.rb +8 -4
  13. data/lib/yardi/error/canceled_guest.rb +9 -0
  14. data/lib/yardi/model/property.rb +27 -0
  15. data/lib/yardi/model/resident.rb +2 -1
  16. data/lib/yardi/parameter/contact_info.rb +1 -1
  17. data/lib/yardi/parameter/prospect.rb +3 -1
  18. data/lib/yardi/parameter/user.rb +1 -2
  19. data/lib/yardi/request/base.rb +28 -5
  20. data/lib/yardi/request/get_property_configurations.rb +36 -0
  21. data/lib/yardi/request/get_residents.rb +3 -2
  22. data/lib/yardi/request/get_yardi_guest_activity.rb +11 -6
  23. data/lib/yardi/request/import_yardi_guest.rb +18 -3
  24. data/lib/yardi/request_section/lead_management.rb +72 -9
  25. data/lib/yardi/request_section/prospect.rb +1 -0
  26. data/lib/yardi/utils/google_cloud_storage.rb +25 -0
  27. data/lib/yardi/utils/request_fetcher.rb +3 -5
  28. data/lib/yardi/utils/request_generator.rb +1 -0
  29. data/lib/yardi/utils/snowflake_event_tracker.rb +107 -0
  30. data/lib/yardi/utils/test_data_fetcher.rb +30 -0
  31. data/lib/yardi/validator/base.rb +114 -0
  32. data/lib/yardi/validator/empty_response.rb +25 -8
  33. data/lib/yardi/validator/error_response.rb +31 -8
  34. data/lib/yardi/validator/fault_response.rb +28 -6
  35. data/lib/yardi/validator/missing_property.rb +20 -4
  36. data/lib/yardi/validator/prospect_eventing.rb +42 -0
  37. data/lib/yardi/validator/resident_eventing.rb +45 -0
  38. data/lib/yardi/version.rb +1 -1
  39. data/lib/yardi.rb +7 -2
  40. data/yardi.gemspec +6 -1
  41. metadata +78 -12
@@ -1,3 +1,4 @@
1
+ require 'yardi/validator/resident_eventing'
1
2
  require_relative 'base'
2
3
 
3
4
  module Yardi
@@ -5,8 +6,8 @@ module Yardi
5
6
  class Residents < Base
6
7
  SOAP_ACTION = 'GetResidents'.freeze
7
8
 
8
- def initialize(property_id)
9
- @property_id = property_id
9
+ def after_initialize(params)
10
+ @property_id = params[:property_id]
10
11
  end
11
12
 
12
13
  private
@@ -34,8 +35,6 @@ module Yardi
34
35
  results.map { |r| create_resident(r) }
35
36
  end
36
37
 
37
- private
38
-
39
38
  # Creates a primary Resident after first creating Resident objects
40
39
  # for roommates under `OtherOccupants`.
41
40
  def create_resident(resident)
@@ -48,12 +47,17 @@ module Yardi
48
47
  # either be a Hash or Array, so we cast it to an Array from the start.
49
48
  def create_roommates(roommates)
50
49
  return unless roommates
50
+
51
51
  roommates = [roommates].flatten
52
52
 
53
53
  roommates.map do |r|
54
54
  Model::Resident.new(r, type: 'roommate')
55
55
  end
56
56
  end
57
+
58
+ def validator_classes
59
+ [Validator::ResidentEventing]
60
+ end
57
61
  end
58
62
  end
59
63
  end
@@ -0,0 +1,9 @@
1
+ require_relative 'error_response'
2
+
3
+ module Yardi
4
+ module Error
5
+ # Raised when a Yardi response contains error message about Canceled Guest
6
+ class CanceledGuest < ErrorResponse
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module Yardi
2
+ module Model
3
+ class Property
4
+ attr_reader :timezone, :remote_id, :marketing_name, :address, :city,
5
+ :state, :postal_code
6
+
7
+ def initialize(property)
8
+ @timezone = property['TimeZone']
9
+ @remote_id = property['Code']
10
+ @marketing_name = property['MarketingName']
11
+ @address = format_address(property['AddressLine1'], property['AddressLine2'], property['AddressLine3'])
12
+ @city = property['City']
13
+ @state = property['State']
14
+ @postal_code = property['PostalCode']
15
+ end
16
+
17
+ private
18
+
19
+ # The xml response has AddressLine1 AddressLine2 and AddressLine3 nodes
20
+ # We should unify it to a single address string
21
+ def format_address(address_line_1, address_line_2, address_line_3)
22
+ address = address_line_1.to_s + ' ' + address_line_2.to_s + ' ' + address_line_3.to_s
23
+ address.strip
24
+ end
25
+ end
26
+ end
27
+ end
@@ -7,7 +7,7 @@ module Yardi
7
7
  class Resident
8
8
  attr_reader :status, :lease_id, :lease_lead_id, :first_name, :last_name,
9
9
  :email, :phones, :unit_name, :move_in_date, :lease_from_date,
10
- :lease_to_date, :type, :roommates
10
+ :lease_to_date, :type, :roommates, :import_resident_id
11
11
 
12
12
  def initialize(resident, type:, roommates: nil)
13
13
  @status = resident['Status']
@@ -23,6 +23,7 @@ module Yardi
23
23
  @lease_to_date = parse_date(resident['LeaseToDate'])
24
24
  @type = type
25
25
  @roommates = roommates || []
26
+ @import_resident_id = resident['import_resident_id']
26
27
  end
27
28
 
28
29
  private
@@ -5,7 +5,7 @@ module Yardi
5
5
 
6
6
  def initialize(email:, cell_phone: nil, home_phone: nil)
7
7
  @email = email
8
- @cell_phone= cell_phone
8
+ @cell_phone = cell_phone
9
9
  @home_phone = home_phone
10
10
  end
11
11
  end
@@ -5,19 +5,21 @@
5
5
  module Yardi
6
6
  module Parameter
7
7
  class Prospect
8
- attr_reader :first_name, :last_name, :email, :phone, :yardi_prospect_id
8
+ attr_reader :first_name, :last_name, :email, :phone, :phones, :yardi_prospect_id
9
9
 
10
10
  def initialize(
11
11
  first_name: nil,
12
12
  last_name: nil,
13
13
  email: nil,
14
14
  phone: nil,
15
+ phones: nil,
15
16
  yardi_prospect_id: nil
16
17
  )
17
18
  @first_name = first_name
18
19
  @last_name = last_name
19
20
  @email = email
20
21
  @phone = phone
22
+ @phones = phones
21
23
  @yardi_prospect_id = yardi_prospect_id
22
24
  end
23
25
  end
@@ -43,8 +43,7 @@ module Yardi
43
43
  move_in_date:,
44
44
  preference_notes:,
45
45
  preferred_floorplan_id:,
46
- preferred_unit_id: nil,
47
- price:
46
+ price:, preferred_unit_id: nil
48
47
  )
49
48
 
50
49
  @beds = beds.nil? || beds == '' ? nil : beds.to_i
@@ -1,6 +1,7 @@
1
1
  require 'yardi/request_section/authentication'
2
2
  require 'yardi/utils/request_fetcher'
3
3
  require 'yardi/utils/request_generator'
4
+ require 'yardi/utils/test_data_fetcher'
4
5
 
5
6
  module Yardi
6
7
  module Request
@@ -23,6 +24,7 @@ module Yardi
23
24
  # method assumes that the subclass will be named the same as the action.
24
25
  class Base
25
26
  attr_reader :connection, :credential, :response
27
+
26
28
  # @param credential [Parameter::Credential] contains the PMC-specific
27
29
  # configuration information needed to make a request. We want to fail
28
30
  # noisily if it's missing, so it is separate from the main params hash.
@@ -45,11 +47,15 @@ module Yardi
45
47
 
46
48
  # @return [String] the XMl response from Yardi
47
49
  def xml
48
- Utils::RequestFetcher.new(
49
- connection: connection,
50
- endpoint: credential.web_service_url,
51
- generator: generator
52
- ).fetch
50
+ if request_test_data?
51
+ fetch_test_data
52
+ else
53
+ Utils::RequestFetcher.new(
54
+ connection: connection,
55
+ endpoint: credential.web_service_url,
56
+ generator: generator
57
+ ).fetch
58
+ end
53
59
  end
54
60
 
55
61
  # This makes it easy for us to see what XML we're about to send when
@@ -92,6 +98,23 @@ module Yardi
92
98
  def interface
93
99
  raise NotImplementedError
94
100
  end
101
+
102
+ def request_test_data?
103
+ params[:test_data] == true
104
+ end
105
+
106
+ def request_name
107
+ self.class.name.split('::').last
108
+ end
109
+
110
+ def fetch_test_data
111
+ case request_name
112
+ when 'GetResidents'
113
+ Utils::TestDataFetcher.residents(params[:property_id])
114
+ when 'GetYardiGuestActivity'
115
+ Utils::TestDataFetcher.guest_card_activity(params[:property_id], params[:prospect])
116
+ end
117
+ end
95
118
  end
96
119
 
97
120
  private_constant :Base
@@ -0,0 +1,36 @@
1
+ require 'yardi/document_parser/properties'
2
+
3
+ require_relative 'base'
4
+
5
+ module Yardi
6
+ module Request
7
+ # Get all property configurations for a given credential
8
+ class GetPropertyConfigurations < Base
9
+ private
10
+
11
+ attr_reader :params
12
+
13
+ def after_initialize(params)
14
+ @params = params
15
+ end
16
+
17
+ def parser
18
+ DocumentParser::Properties.new(params)
19
+ end
20
+
21
+ def soap_body_sections
22
+ [
23
+ RequestSection::Authentication.new(credential)
24
+ ]
25
+ end
26
+
27
+ def soap_action
28
+ 'GetPropertyConfigurations'
29
+ end
30
+
31
+ def interface
32
+ 'ItfILSGuestCard'
33
+ end
34
+ end
35
+ end
36
+ end
@@ -9,15 +9,16 @@ module Yardi
9
9
  class GetResidents < Base
10
10
  private
11
11
 
12
- attr_reader :property_id
12
+ attr_reader :property_id, :params
13
13
 
14
14
  def after_initialize(params)
15
15
  @property_id = params[:property_id]
16
+ @params = params
16
17
  raise ArgumentError, ':property_id is required' unless property_id
17
18
  end
18
19
 
19
20
  def parser
20
- DocumentParser::Residents.new(property_id)
21
+ DocumentParser::Residents.new(params)
21
22
  end
22
23
 
23
24
  def soap_body_sections
@@ -48,19 +48,20 @@ module Yardi
48
48
  # Private methods
49
49
  private
50
50
 
51
- attr_reader :property_id, :prospect
51
+ attr_reader :property_id, :prospect, :params, :with_or, :send_prospect_events
52
52
 
53
53
  def after_initialize(params)
54
54
  @property_id = params[:property_id]
55
55
  @prospect = params[:prospect]
56
+ @params = params
57
+ @with_or = params[:with_or] || false
58
+ @send_prospect_events = params[:send_prospect_events].nil? ? true : params[:send_prospect_events]
56
59
 
57
- unless property_id && prospect
58
- raise ArgumentError, ':property_id and :prospect are required'
59
- end
60
+ raise ArgumentError, ':property_id and :prospect are required' unless property_id && prospect
60
61
  end
61
62
 
62
63
  def parser
63
- DocumentParser::Prospects.new
64
+ DocumentParser::Prospects.new(params)
64
65
  end
65
66
 
66
67
  def soap_body_sections
@@ -74,7 +75,11 @@ module Yardi
74
75
  end
75
76
 
76
77
  def soap_action
77
- 'GetYardiGuestActivity_Search'
78
+ if with_or
79
+ 'GetYardiGuestActivity_SearchWithOR'
80
+ else
81
+ 'GetYardiGuestActivity_Search'
82
+ end
78
83
  end
79
84
 
80
85
  def interface
@@ -19,9 +19,12 @@ module Yardi
19
19
  # 'tour', 'price inquiry', etc.
20
20
  # @param user [Parameter::User] The renter
21
21
  class ImportYardiGuest < Base
22
+ CREATE_GUESTCARD_ACTION = 'create'.freeze
23
+ VALID_GUESTCARD_ACTIONS = %w[inactivate create reactivate update].freeze
24
+
22
25
  private
23
26
 
24
- attr_reader :agent, :lead_source, :property, :reason, :user
27
+ attr_reader :agent, :lead_source, :property, :reason, :user, :guestcard_action, :params
25
28
 
26
29
  def after_initialize(params)
27
30
  @agent = params[:agent]
@@ -29,8 +32,11 @@ module Yardi
29
32
  @property = params[:property]
30
33
  @reason = params[:reason]
31
34
  @user = params[:user]
35
+ @guestcard_action = params[:guestcard_action] || CREATE_GUESTCARD_ACTION
36
+ @params = params
32
37
 
33
38
  check_required_params
39
+ validate_action
34
40
  end
35
41
 
36
42
  def check_required_params
@@ -41,8 +47,16 @@ module Yardi
41
47
  end
42
48
  end
43
49
 
50
+ def validate_action
51
+ unless VALID_GUESTCARD_ACTIONS.include? guestcard_action
52
+ message =
53
+ "a guestcard_action of 'inactivate', 'create', 'reactivate', or 'update' is required"
54
+ raise ArgumentError, message
55
+ end
56
+ end
57
+
44
58
  def parser
45
- DocumentParser::GuestCardImportResponseObject.new
59
+ DocumentParser::GuestCardImportResponseObject.new(params)
46
60
  end
47
61
 
48
62
  def soap_body_sections
@@ -56,7 +70,8 @@ module Yardi
56
70
  lead_source: lead_source,
57
71
  property: property,
58
72
  reason: reason,
59
- user: user
73
+ user: user,
74
+ guestcard_action: guestcard_action
60
75
  )
61
76
  ]
62
77
  end
@@ -4,12 +4,13 @@ module Yardi
4
4
  module RequestSection
5
5
  # Generate the LeadManagement section of a Yardi request
6
6
  class LeadManagement
7
- def initialize(agent:, lead_source:, property:, reason:, user:)
7
+ def initialize(agent:, lead_source:, property:, reason:, user:, guestcard_action:)
8
8
  @agent = agent
9
9
  @lead_source = lead_source
10
10
  @property = property
11
11
  @reason = reason
12
12
  @user = user
13
+ @guestcard_action = guestcard_action
13
14
  end
14
15
 
15
16
  def generate(xml_builder)
@@ -22,15 +23,31 @@ module Yardi
22
23
 
23
24
  private
24
25
 
25
- attr_reader :agent, :lead_source, :property, :reason, :user
26
+ attr_reader :agent, :lead_source, :property, :reason, :user, :guestcard_action
26
27
 
28
+ # guestcard_action for yardi gem can be 'create', 'inactivate', 'reactivate', or 'update'.
29
+ # When guestcard_action is 'create' we need to generate first_contact_event_xml.
30
+ # When guestcard_action is 'inactivate' we need to generate both the first_contact_event_xml
31
+ # and the cancel_event_xml.
32
+ # When the guestcard_action is 'reactivate' we need to generate reactivate_event_xml
33
+ # When the guestcard_action is 'update' we need to generate the update_event_xml
27
34
  def prospect_xml(xml_builder)
28
35
  xml_builder.Prospect do |prospect_xml|
29
36
  customers_xml(prospect_xml)
30
37
  preferences_xml(prospect_xml)
31
38
 
32
39
  prospect_xml.Events do |events_xml|
33
- first_contact_event_xml(events_xml)
40
+ case guestcard_action
41
+ when 'create'
42
+ first_contact_event_xml(events_xml)
43
+ when 'inactivate'
44
+ first_contact_event_xml(events_xml)
45
+ cancel_event_xml(events_xml)
46
+ when 'reactivate'
47
+ reactivate_event_xml(events_xml)
48
+ when 'update'
49
+ update_event_xml(events_xml)
50
+ end
34
51
  tour_xml(events_xml) unless property.tour_time.nil?
35
52
  end
36
53
  end
@@ -92,13 +109,9 @@ module Yardi
92
109
  # Rent and bedrooms are empty nodes with attributes for values.
93
110
  # Yardi doesn't like having an empty string for either of these
94
111
  # attributes, so we leave the node out if we don't have any data.
95
- unless user.price.nil?
96
- preferences_xml.DesiredRent('Exact' => user.price) {}
97
- end
112
+ preferences_xml.DesiredRent('Exact' => user.price) {} unless user.price.nil?
98
113
 
99
- unless user.beds.nil?
100
- preferences_xml.DesiredNumBedrooms('Exact' => user.beds) {}
101
- end
114
+ preferences_xml.DesiredNumBedrooms('Exact' => user.beds) {} unless user.beds.nil?
102
115
 
103
116
  preferences_xml.Comment user.preference_notes
104
117
  end
@@ -118,6 +131,56 @@ module Yardi
118
131
  end
119
132
  end
120
133
 
134
+ # To create a cancel event for an inactive guestcard,
135
+ # EventType should be 'Cancel' and FirstContact should be false
136
+ # cancel_time should be one second after first_contact_time
137
+ def cancel_event_xml(xml_builder)
138
+ cancel_time = property.first_contact_time + 1
139
+ event_attrs = {
140
+ 'EventDate' => cancel_time.iso8601,
141
+ 'EventType' => 'Cancel'
142
+ }
143
+ xml_builder.Event(event_attrs) do |event_xml|
144
+ agent_xml(event_xml)
145
+ event_xml.EventReasons reason
146
+ event_xml.FirstContact false
147
+ event_xml.Comments user.message
148
+ event_xml.TransactionSource lead_source
149
+ end
150
+ end
151
+
152
+ # To create a reactivate event for an inactive guestcard,
153
+ # EventType should be 'ReActivate' and FirstContact should be false
154
+ def reactivate_event_xml(xml_builder)
155
+ event_attrs = {
156
+ 'EventDate' => property.first_contact_time.iso8601,
157
+ 'EventType' => 'ReActivate'
158
+ }
159
+ xml_builder.Event(event_attrs) do |event_xml|
160
+ agent_xml(event_xml)
161
+ event_xml.EventReasons reason
162
+ event_xml.FirstContact false
163
+ event_xml.Comments user.message
164
+ event_xml.TransactionSource lead_source
165
+ end
166
+ end
167
+
168
+ # To create an update event for a guestcard,
169
+ # EventType should be 'Email' and FirstContact should be false.
170
+ def update_event_xml(xml_builder)
171
+ event_attrs = {
172
+ 'EventDate' => property.first_contact_time.iso8601,
173
+ 'EventType' => 'Email'
174
+ }
175
+ xml_builder.Event(event_attrs) do |event_xml|
176
+ agent_xml(event_xml)
177
+ event_xml.EventReasons reason
178
+ event_xml.FirstContact false
179
+ event_xml.Comments user.message
180
+ event_xml.TransactionSource lead_source
181
+ end
182
+ end
183
+
121
184
  def agent_xml(xml_builder)
122
185
  xml_builder.Agent do |agent_xml|
123
186
  agent_xml.AgentName do |agent_name_xml|
@@ -19,6 +19,7 @@ module Yardi
19
19
  xml_builder['itf'].LastName prospect.last_name
20
20
  xml_builder['itf'].EmailAddress prospect.email
21
21
  xml_builder['itf'].PhoneNumber prospect.phone
22
+ prospect.phones&.each { |phone| xml_builder['itf'].PhoneNumber phone }
22
23
  xml_builder['itf'].ThirdPartyId prospect.yardi_prospect_id
23
24
  xml_builder['itf'].FederalId
24
25
  end
@@ -0,0 +1,25 @@
1
+ require 'google/cloud/storage'
2
+
3
+ require 'yardi/utils'
4
+
5
+ module Yardi
6
+ module Utils
7
+ class GoogleCloudStorage
8
+ def self.read_file(file_path:, bucket: Yardi.config.gcs_bucket)
9
+ bucket = client.bucket(bucket)
10
+ file = bucket.file(file_path)
11
+ if file
12
+ downloaded = file.download
13
+ downloaded.rewind
14
+ downloaded.read
15
+ else
16
+ ''
17
+ end
18
+ end
19
+
20
+ def self.client
21
+ @client ||= Google::Cloud::Storage.new
22
+ end
23
+ end
24
+ end
25
+ end
@@ -23,9 +23,7 @@ module Yardi
23
23
 
24
24
  response = perform!
25
25
 
26
- if response.status == 404
27
- raise Yardi::Error::ResourceNotFound, response.body
28
- end
26
+ raise Yardi::Error::ResourceNotFound, response.body if response.status == 404
29
27
 
30
28
  response.body
31
29
  end
@@ -39,8 +37,8 @@ module Yardi
39
37
  request.body = generator.body
40
38
  request.headers = generator.headers
41
39
  end
42
- rescue Errno::EADDRNOTAVAIL => error
43
- raise Yardi::Error::ConnectionError, error.message
40
+ rescue Errno::EADDRNOTAVAIL => e
41
+ raise Yardi::Error::ConnectionError, e.message
44
42
  end
45
43
  end
46
44
  end
@@ -44,6 +44,7 @@ module Yardi
44
44
 
45
45
  def xml_doc_body
46
46
  return nil if sections[:xml_doc].nil?
47
+
47
48
  body_fragment = Nokogiri::XML::DocumentFragment.parse('')
48
49
  Nokogiri::XML::Builder.with(body_fragment) do |xml_builder|
49
50
  sections[:xml_doc].each do |section|
@@ -0,0 +1,107 @@
1
+ require 'securerandom'
2
+ require 'event_tracker'
3
+ require 'yardi/utils'
4
+ require 'yardi'
5
+
6
+ module Yardi
7
+ module Utils
8
+ class SnowflakeEventTracker
9
+ IMPORT_PMS_RESIDENT_EVENT = 'import_pms_resident'
10
+ IMPORT_PMS_PROSPECT_EVENT = 'import_pms_prospect'
11
+
12
+ def self.track_pms_resident_event(
13
+ import_resident_id:, resident_type:, request_params:, unit_name:, remote_lease_id: nil,
14
+ move_in_date: nil,
15
+ lease_to: nil,
16
+ lease_from: nil,
17
+ first_name_present: false,
18
+ last_name_present: false,
19
+ email_present: false,
20
+ phones_count: 0,
21
+ resident_id: nil,
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[:property_id],
29
+ billing_config_id: request_params[:billing_config_id],
30
+ remote_id: request_params[:remote_id],
31
+ pms_type: 'yardi',
32
+ import_id: request_params[:import_id],
33
+ pmc_id: request_params[:pmc_id],
34
+ service: Yardi.config.app_name
35
+ ),
36
+ remote_lease_id: remote_lease_id,
37
+ import_resident_id: import_resident_id,
38
+ resident_type: resident_type,
39
+ api_name: 'GetResidents',
40
+ request_params: EventTracker::ResourceFactory::PmsResident.build_request_params(
41
+ start_date: request_params[:start_date].nil? ? nil : request_params[:start_date].to_time,
42
+ end_date: request_params[:end_date].nil? ? nil : request_params[:end_date].to_time,
43
+ prospect_id: nil,
44
+ pmc_id: request_params[:pmc_id],
45
+ remote_id: request_params[:remote_id],
46
+ traffic_source_id: nil
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
+ unit_name: unit_name,
56
+ resident_id: resident_id,
57
+ move_in_report_type: 'yardi_api',
58
+ error: error
59
+ )
60
+ )
61
+ end
62
+ end
63
+
64
+ def self.track_pms_prospect_event(
65
+ request_params:, first_name_present:, last_name_present:, email_present:, phone_present:, remote_lease_id: nil,
66
+ contact_date: nil,
67
+ contact_source: nil,
68
+ remote_prospect_id: nil,
69
+ error: nil
70
+ )
71
+ EventTracker.track_process_events(name: IMPORT_PMS_PROSPECT_EVENT) do |events|
72
+ events.add_imported_event(
73
+ EventTracker::ResourceFactory.build_pms_prospect(
74
+ billing_import: EventTracker::BillingImportFactory.build_billing_import(
75
+ property_id: request_params[:property_id],
76
+ billing_config_id: request_params[:billing_config_id],
77
+ remote_id: request_params[:remote_id],
78
+ pms_type: 'yardi',
79
+ import_id: request_params[:import_id],
80
+ pmc_id: request_params[:pmc_id],
81
+ service: Yardi.config.app_name
82
+ ),
83
+ remote_lease_id: remote_lease_id,
84
+ import_resident_id: request_params[:import_resident_id] || '',
85
+ resident_type: 'PRIMARY',
86
+ api_name: 'GetYardiGuestActivity_Search',
87
+ request_params: EventTracker::ResourceFactory::PmsProspect.build_request_params(
88
+ pmc_id: request_params[:pmc_id],
89
+ remote_id: request_params[:remote_id],
90
+ prospect_id: request_params[:prospect_id],
91
+ first_name_present: first_name_present,
92
+ last_name_present: last_name_present,
93
+ email_present: email_present,
94
+ phone_present: phone_present
95
+ ),
96
+ contact_date: contact_date,
97
+ contact_source: contact_source,
98
+ remote_prospect_id: remote_prospect_id,
99
+ move_in_report_type: 'yardi_api',
100
+ error: error
101
+ )
102
+ )
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,30 @@
1
+ require 'yardi/utils'
2
+ require 'yardi/utils/google_cloud_storage'
3
+
4
+ module Yardi
5
+ module Utils
6
+ class TestDataFetcher
7
+ RESIDENTS_PATH = 'test_data/residents/'
8
+ GUESTCARD_ACTIVITY_PATH = 'test_data/yardi_prospects/'
9
+ def self.residents(property_id)
10
+ GoogleCloudStorage.read_file(file_path: RESIDENTS_PATH + "#{property_id}.xml")
11
+ end
12
+
13
+ def self.guest_card_activity(property_id, prospect)
14
+ search_by = case prospect
15
+ when -> (p) { p.yardi_prospect_id }
16
+ { '/prospect_id/' => prospect.yardi_prospect_id }
17
+ when -> (p) { p.email }
18
+ { '/email/' => prospect.email.gsub(/\./,'') }
19
+ when -> (p) { p.first_name } && -> (p) { p.last_name }
20
+ { '/name/' => prospect.first_name + ' ' + prospect.last_name }
21
+ when -> (p) { p.phone }
22
+ { '/phone/' => prospect.phone }
23
+ end
24
+
25
+ file_path = GUESTCARD_ACTIVITY_PATH + property_id.to_s + search_by.keys.first + search_by[search_by.keys.first] + '.xml'
26
+ GoogleCloudStorage.read_file(file_path: file_path)
27
+ end
28
+ end
29
+ end
30
+ end