yardi 4.0.8 → 4.11.0

Sign up to get free protection for your applications and to get access to all the features.
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 +27 -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 +27 -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
@@ -23,6 +23,7 @@ module Yardi
23
23
  # method assumes that the subclass will be named the same as the action.
24
24
  class Base
25
25
  attr_reader :connection, :credential, :response
26
+
26
27
  # @param credential [Parameter::Credential] contains the PMC-specific
27
28
  # configuration information needed to make a request. We want to fail
28
29
  # noisily if it's missing, so it is separate from the main params hash.
@@ -45,11 +46,15 @@ module Yardi
45
46
 
46
47
  # @return [String] the XMl response from Yardi
47
48
  def xml
48
- Utils::RequestFetcher.new(
49
- connection: connection,
50
- endpoint: credential.web_service_url,
51
- generator: generator
52
- ).fetch
49
+ if request_test_data?
50
+ fetch_test_data
51
+ else
52
+ Utils::RequestFetcher.new(
53
+ connection: connection,
54
+ endpoint: credential.web_service_url,
55
+ generator: generator
56
+ ).fetch
57
+ end
53
58
  end
54
59
 
55
60
  # This makes it easy for us to see what XML we're about to send when
@@ -92,6 +97,23 @@ module Yardi
92
97
  def interface
93
98
  raise NotImplementedError
94
99
  end
100
+
101
+ def request_test_data?
102
+ params[:test_data] == true
103
+ end
104
+
105
+ def request_name
106
+ self.class.name.split('::').last
107
+ end
108
+
109
+ def fetch_test_data
110
+ case request_name
111
+ when 'GetResidents'
112
+ Utils::TestDataFetcher.residents(params[:property_id])
113
+ when 'GetYardiGuestActivity'
114
+ Utils::TestDataFetcher.guest_card_activity(params[:property_id], params[:prospect])
115
+ end
116
+ end
95
117
  end
96
118
 
97
119
  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
+ module Yardi
4
+ module Utils
5
+ class GoogleCloudStorage
6
+ GCS_BUCKET = Yardi.config.gcs_bucket
7
+
8
+ def self.read_file(file_path:, bucket: 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,27 @@
1
+ module Yardi
2
+ module Utils
3
+ class TestDataFetcher
4
+ RESIDENTS_PATH = 'test-data/residents/'
5
+ GUESTCARD_ACTIVITY_PATH = 'test-data/yardi_prospects/'
6
+ def self.residents(property_id)
7
+ GoogleCloudStorage.read_file(file_path: RESIDENTS_PATH + "#{property_id}.xml")
8
+ end
9
+
10
+ def self.guest_card_activity(property_id, prospect)
11
+ search_by = case prospect
12
+ when -> (p) { p.yardi_prospect_id }
13
+ { '/prospect_id/' => prospect.yardi_prospect_id }
14
+ when -> (p) { p.email }
15
+ { '/email/' => prospect.email.gsub(/\./,'') }
16
+ when -> (p) { p.first_name } && -> (p) { p.last_name }
17
+ { '/name/' => prospect.first_name + ' ' + prospect.last_name }
18
+ when -> (p) { p.phone }
19
+ { '/phone/' => prospect.phone }
20
+ end
21
+
22
+ file_path = GUESTCARD_ACTIVITY_PATH + property_id.to_s + search_by.keys.first + search_by[search_by.keys.first] + '.xml'
23
+ GoogleCloudStorage.read_file(file_path: file_path)
24
+ end
25
+ end
26
+ end
27
+ end