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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 23da65dd97a13b80552415335b257aad1f1ae7f8
4
- data.tar.gz: 75a31101f34ac6e8d129cc97aeb82b0f05710c86
2
+ SHA256:
3
+ metadata.gz: 68fbe6d401e805c229f86a032096d90ebed0a01a4905a1bfb3969f81882ee573
4
+ data.tar.gz: 933e0b3d08fc6efdadb5d63baf13da4bc0baddd920cf49768ced911105085dc5
5
5
  SHA512:
6
- metadata.gz: a8ee7e3f3e4edeb6a33dea96055ae771e197870df3df603e9ca90145faa10afa7497725b8fb4884d5e39b2bf61bcb79575ef3162f677990e58209e23db59aae8
7
- data.tar.gz: b1f9f8ebde63520dcf5242153dcc37f939e63e2faa3d7b4950ac7147a70e195f54873804ed190291d427212599dc3499567dd7f5d9e0540ea64344854c693529
6
+ metadata.gz: 2c31996f6eb55e04979218a35347ce08fd1b676fa12013cc8c6478b306fe86f8fc8031eec764577d51ebc98776bbfc415a068772ef5998dbdae2f7202886f75e
7
+ data.tar.gz: 7db5eb29a4889fd1e1073ed9a20ef45b16499a3d1de3651234234da5743920627a15b77f687183e959b3e6c143fe012b73dd1ebf2e591a0653f88c4b49ccb5f6
data/.gitignore CHANGED
@@ -3,3 +3,6 @@ Gemfile.lock
3
3
  yardi-*.gem
4
4
  # Ignore bundler config
5
5
  /.bundle
6
+
7
+ # Rubocop cache files
8
+ .rubocop-http*
data/.rubocop.yml CHANGED
@@ -1,20 +1,7 @@
1
- AllCops:
2
- TargetRubyVersion: 2.3
1
+ require:
2
+ - rubocop-rspec
3
+ - rubocop-rails
3
4
 
4
- Style/MultilineMethodCallIndentation:
5
- EnforcedStyle: indented
6
-
7
- Style/NumericLiterals:
8
- Enabled: false
9
-
10
- Style/FrozenStringLiteralComment:
11
- Enabled: false
12
-
13
- # We prefer [] over () for % delimited Arrays such as %w and %i.
14
- PercentLiteralDelimiters:
15
- PreferredDelimiters:
16
- '%i': '[]'
17
- '%w': '[]'
18
-
19
- Performance/Casecmp:
20
- Enabled: false
5
+ inherit_from:
6
+ - https://raw.githubusercontent.com/apartmentlist/style/rubocop-2022/ruby/global.yml
7
+ - .rubocop_todo.yml
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,264 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --exclude-limit 100`
3
+ # on 2022-01-14 17:22:04 UTC using RuboCop version 1.23.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 2
10
+ # Configuration parameters: AllowedMethods.
11
+ # AllowedMethods: enums
12
+ Lint/ConstantDefinitionInBlock:
13
+ Exclude:
14
+ - 'spec/yardi/utils/request_generator_spec.rb'
15
+
16
+ # Offense count: 1
17
+ Lint/DuplicateHashKey:
18
+ Exclude:
19
+ - 'spec/behaviors/get_residents_spec.rb'
20
+
21
+ # Offense count: 6
22
+ # Configuration parameters: AllowComments, AllowEmptyLambdas.
23
+ Lint/EmptyBlock:
24
+ Exclude:
25
+ - 'lib/yardi/request_section/lead_management.rb'
26
+ - 'spec/yardi/utils/snowflake_event_tracker_spec.rb'
27
+
28
+ # Offense count: 6
29
+ Lint/MissingSuper:
30
+ Exclude:
31
+ - 'lib/yardi/validator/empty_response.rb'
32
+ - 'lib/yardi/validator/error_response.rb'
33
+ - 'lib/yardi/validator/fault_response.rb'
34
+ - 'lib/yardi/validator/missing_property.rb'
35
+ - 'lib/yardi/validator/prospect_eventing.rb'
36
+ - 'lib/yardi/validator/resident_eventing.rb'
37
+
38
+ # Offense count: 1
39
+ Lint/MixedRegexpCaptureTypes:
40
+ Exclude:
41
+ - 'lib/yardi/document_parser/guest_card_import_response_object.rb'
42
+
43
+ # Offense count: 1
44
+ # Cop supports --auto-correct.
45
+ Lint/NonDeterministicRequireOrder:
46
+ Exclude:
47
+ - 'spec/spec_helper.rb'
48
+
49
+ # Offense count: 1
50
+ Lint/UselessAssignment:
51
+ Exclude:
52
+ - 'lib/yardi/document_parser/base.rb'
53
+
54
+ # Offense count: 1
55
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
56
+ # IgnoredMethods: refine
57
+ Metrics/BlockLength:
58
+ Max: 51
59
+
60
+ # Offense count: 6
61
+ # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
62
+ Metrics/ParameterLists:
63
+ Max: 14
64
+
65
+ # Offense count: 3
66
+ # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
67
+ # SupportedStyles: snake_case, normalcase, non_integer
68
+ # AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
69
+ Naming/VariableNumber:
70
+ Exclude:
71
+ - 'lib/yardi/model/property.rb'
72
+
73
+ # Offense count: 43
74
+ # Configuration parameters: Prefixes.
75
+ # Prefixes: when, with, without
76
+ RSpec/ContextWording:
77
+ Exclude:
78
+ - 'spec/behaviors/get_property_configurations_spec.rb'
79
+ - 'spec/behaviors/get_residents_spec.rb'
80
+ - 'spec/behaviors/get_yardi_guest_activity_spec.rb'
81
+ - 'spec/yardi/request_section/lead_management_spec.rb'
82
+ - 'spec/yardi/utils/request_fetcher_spec.rb'
83
+
84
+ # Offense count: 8
85
+ # Cop supports --auto-correct.
86
+ # Configuration parameters: SkipBlocks, EnforcedStyle.
87
+ # SupportedStyles: described_class, explicit
88
+ RSpec/DescribedClass:
89
+ Exclude:
90
+ - 'spec/yardi/request_section/authentication_spec.rb'
91
+ - 'spec/yardi/request_section/lead_management_spec.rb'
92
+ - 'spec/yardi/request_section/prospect_spec.rb'
93
+ - 'spec/yardi/request_section/residents_spec.rb'
94
+ - 'spec/yardi/utils/request_fetcher_spec.rb'
95
+ - 'spec/yardi/utils/request_generator_spec.rb'
96
+ - 'spec/yardi/utils/snowflake_event_tracker_spec.rb'
97
+
98
+ # Offense count: 1
99
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
100
+ # Include: **/*_spec*rb*, **/spec/**/*
101
+ RSpec/FilePath:
102
+ Exclude:
103
+ - 'spec/yardi/models/resident_spec.rb'
104
+
105
+ # Offense count: 2
106
+ RSpec/IteratedExpectation:
107
+ Exclude:
108
+ - 'spec/behaviors/get_property_configurations_spec.rb'
109
+ - 'spec/behaviors/get_residents_spec.rb'
110
+
111
+ # Offense count: 2
112
+ RSpec/LeakyConstantDeclaration:
113
+ Exclude:
114
+ - 'spec/yardi/utils/request_generator_spec.rb'
115
+
116
+ # Offense count: 7
117
+ # Cop supports --auto-correct.
118
+ # Configuration parameters: EnforcedStyle.
119
+ # SupportedStyles: strict, flexible
120
+ Rails/TimeZone:
121
+ Exclude:
122
+ - 'spec/behaviors/import_yardi_guest_spec.rb'
123
+ - 'spec/yardi/request_section/lead_management_spec.rb'
124
+
125
+ # Offense count: 1
126
+ # Cop supports --auto-correct.
127
+ Style/CaseLikeIf:
128
+ Exclude:
129
+ - 'lib/yardi/validator/error_response.rb'
130
+
131
+ # Offense count: 29
132
+ # Configuration parameters: AllowedConstants.
133
+ Style/Documentation:
134
+ Exclude:
135
+ - 'lib/yardi/document_parser.rb'
136
+ - 'lib/yardi/document_parser/properties.rb'
137
+ - 'lib/yardi/document_parser/residents.rb'
138
+ - 'lib/yardi/model/event.rb'
139
+ - 'lib/yardi/model/guest_card_response.rb'
140
+ - 'lib/yardi/model/property.rb'
141
+ - 'lib/yardi/model/resident.rb'
142
+ - 'lib/yardi/parameter/contact_info.rb'
143
+ - 'lib/yardi/parameter/property.rb'
144
+ - 'lib/yardi/parameter/prospect.rb'
145
+ - 'lib/yardi/utils.rb'
146
+ - 'lib/yardi/utils/configuration_validator.rb'
147
+ - 'lib/yardi/utils/phone_parser.rb'
148
+ - 'lib/yardi/utils/snowflake_event_tracker.rb'
149
+ - 'lib/yardi/validator.rb'
150
+ - 'lib/yardi/validator/base.rb'
151
+ - 'lib/yardi/validator/prospect_eventing.rb'
152
+ - 'lib/yardi/validator/resident_eventing.rb'
153
+ - 'spec/spec_helper.rb'
154
+ - 'spec/yardi/request_section/authentication_spec.rb'
155
+ - 'spec/yardi/request_section/lead_management_spec.rb'
156
+ - 'spec/yardi/request_section/prospect_spec.rb'
157
+ - 'spec/yardi/request_section/residents_spec.rb'
158
+ - 'spec/yardi/utils/configuration_validator_spec.rb'
159
+ - 'spec/yardi/utils/request_fetcher_spec.rb'
160
+ - 'spec/yardi/utils/request_generator_spec.rb'
161
+ - 'spec/yardi/utils/snowflake_event_tracker_spec.rb'
162
+
163
+ # Offense count: 73
164
+ # Cop supports --auto-correct.
165
+ # Configuration parameters: EnforcedStyle.
166
+ # SupportedStyles: always, always_true, never
167
+ Style/FrozenStringLiteralComment:
168
+ Exclude:
169
+ - 'Gemfile'
170
+ - 'Rakefile'
171
+ - 'bin/console'
172
+ - 'config/multi_xml.rb'
173
+ - 'lib/yardi.rb'
174
+ - 'lib/yardi/document_parser.rb'
175
+ - 'lib/yardi/document_parser/base.rb'
176
+ - 'lib/yardi/document_parser/guest_card_import_response_object.rb'
177
+ - 'lib/yardi/document_parser/properties.rb'
178
+ - 'lib/yardi/document_parser/prospects.rb'
179
+ - 'lib/yardi/document_parser/residents.rb'
180
+ - 'lib/yardi/error/base.rb'
181
+ - 'lib/yardi/error/canceled_guest.rb'
182
+ - 'lib/yardi/error/connection_error.rb'
183
+ - 'lib/yardi/error/empty_response.rb'
184
+ - 'lib/yardi/error/error_response.rb'
185
+ - 'lib/yardi/error/fault_response.rb'
186
+ - 'lib/yardi/error/guests_not_found.rb'
187
+ - 'lib/yardi/error/invalid_configuration.rb'
188
+ - 'lib/yardi/error/missing_property.rb'
189
+ - 'lib/yardi/error/no_results.rb'
190
+ - 'lib/yardi/error/resource_not_found.rb'
191
+ - 'lib/yardi/error/service_unavailable.rb'
192
+ - 'lib/yardi/error/unparsable_response.rb'
193
+ - 'lib/yardi/model/event.rb'
194
+ - 'lib/yardi/model/guest_card_response.rb'
195
+ - 'lib/yardi/model/property.rb'
196
+ - 'lib/yardi/model/prospect.rb'
197
+ - 'lib/yardi/parameter/agent.rb'
198
+ - 'lib/yardi/parameter/contact_info.rb'
199
+ - 'lib/yardi/parameter/credential.rb'
200
+ - 'lib/yardi/parameter/property.rb'
201
+ - 'lib/yardi/parameter/prospect.rb'
202
+ - 'lib/yardi/parameter/user.rb'
203
+ - 'lib/yardi/request/base.rb'
204
+ - 'lib/yardi/request/get_property_configurations.rb'
205
+ - 'lib/yardi/request/get_residents.rb'
206
+ - 'lib/yardi/request/get_yardi_guest_activity.rb'
207
+ - 'lib/yardi/request/import_yardi_guest.rb'
208
+ - 'lib/yardi/request_section.rb'
209
+ - 'lib/yardi/request_section/authentication.rb'
210
+ - 'lib/yardi/request_section/lead_management.rb'
211
+ - 'lib/yardi/request_section/prospect.rb'
212
+ - 'lib/yardi/request_section/residents.rb'
213
+ - 'lib/yardi/utils.rb'
214
+ - 'lib/yardi/utils/configuration_validator.rb'
215
+ - 'lib/yardi/utils/phone_parser.rb'
216
+ - 'lib/yardi/utils/request_fetcher.rb'
217
+ - 'lib/yardi/utils/request_generator.rb'
218
+ - 'lib/yardi/utils/snowflake_event_tracker.rb'
219
+ - 'lib/yardi/validator.rb'
220
+ - 'lib/yardi/validator/base.rb'
221
+ - 'lib/yardi/validator/empty_response.rb'
222
+ - 'lib/yardi/validator/error_response.rb'
223
+ - 'lib/yardi/validator/fault_response.rb'
224
+ - 'lib/yardi/validator/missing_property.rb'
225
+ - 'lib/yardi/validator/prospect_eventing.rb'
226
+ - 'lib/yardi/validator/resident_eventing.rb'
227
+ - 'spec/behaviors/get_property_configurations_spec.rb'
228
+ - 'spec/behaviors/get_residents_spec.rb'
229
+ - 'spec/behaviors/get_yardi_guest_activity_spec.rb'
230
+ - 'spec/behaviors/import_yardi_guest_spec.rb'
231
+ - 'spec/spec_helper.rb'
232
+ - 'spec/yardi/models/resident_spec.rb'
233
+ - 'spec/yardi/request_section/authentication_spec.rb'
234
+ - 'spec/yardi/request_section/lead_management_spec.rb'
235
+ - 'spec/yardi/request_section/prospect_spec.rb'
236
+ - 'spec/yardi/request_section/residents_spec.rb'
237
+ - 'spec/yardi/utils/configuration_validator_spec.rb'
238
+ - 'spec/yardi/utils/request_fetcher_spec.rb'
239
+ - 'spec/yardi/utils/request_generator_spec.rb'
240
+ - 'spec/yardi/utils/snowflake_event_tracker_spec.rb'
241
+ - 'spec/yardi_spec.rb'
242
+
243
+ # Offense count: 3
244
+ # Cop supports --auto-correct.
245
+ # Configuration parameters: EnforcedStyle.
246
+ # SupportedStyles: literals, strict
247
+ Style/MutableConstant:
248
+ Exclude:
249
+ - 'lib/yardi/utils/snowflake_event_tracker.rb'
250
+ - 'lib/yardi/validator/missing_property.rb'
251
+
252
+ # Offense count: 1
253
+ # Cop supports --auto-correct.
254
+ # Configuration parameters: Mode.
255
+ Style/StringConcatenation:
256
+ Exclude:
257
+ - 'lib/yardi/model/property.rb'
258
+
259
+ # Offense count: 1
260
+ # Cop supports --auto-correct.
261
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
262
+ # URISchemes: http, https
263
+ Layout/LineLength:
264
+ Max: 631
data/Gemfile CHANGED
@@ -2,3 +2,14 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in yardi.gemspec
4
4
  gemspec
5
+
6
+ gem 'event_tracker', git: 'https://github.com/apartmentlist/eventing.git', glob: 'clients/ruby/event_tracker.gemspec',
7
+ tag: 'rb1.28.0'
8
+
9
+ gem 'google-cloud-storage'
10
+
11
+ gem 'rubocop', '~> 1.23', group: :development
12
+
13
+ gem 'rubocop-rspec', '~> 2.6', group: :development
14
+
15
+ gem 'rubocop-rails', '~> 2.12', group: :development
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![CircleCI](https://circleci.com/gh/apartmentlist/yardi.svg?style=svg&circle-token=f257321b5c0e4a15a49eda74aa869a09d6db2f19)](https://circleci.com/gh/apartmentlist/yardi)
2
2
 
3
3
  # yardi
4
+
4
5
  A Ruby client for v4 of Yardi's Guestcard (and soon ILS) API
5
6
 
6
7
  ## Installation
@@ -31,6 +32,8 @@ Yardi.configure do |config|
31
32
  config.license_key = ENV['LICENSE_KEY']
32
33
  config.entity = 'Apartment List'
33
34
  config.platform = 'SQL Server'
35
+ config.enable_event_tracking = true
36
+ config.gcs_bucket = ENV['_GCS_BUCKET']
34
37
  end
35
38
  ```
36
39
 
@@ -63,32 +66,36 @@ To request an action, instantiate the appropriate class (see below) and invoke
63
66
  `#perform` on it. The API response will be parsed and returned as a ruby object.
64
67
 
65
68
  #### Yardi::Action::ImportYardiGuest_Login
69
+
66
70
  Insert a guest card into Yardi's system.
67
71
 
68
72
  ##### Initialization parameters
69
73
 
70
- * `agent [Yardi::Parameter::Agent]`
71
- * `credential [Yardi::Parameter::Credential]`
72
- information needed to authenticate with Yardi
73
- * `lead_source [String]` what Yardi calls TransactionSource
74
- * `reason [String]` what Yardi calls Event Reasons. This is the reason for
75
- the event, e.g. price inquiry, tour, etc.
76
- * `property [Yardi::Parameter::Property]` the property to associate the guest
77
- card with
78
- * `user [Yardi::Parameter::User]` the user to associate the guest card with
74
+ - `agent [Yardi::Parameter::Agent]`
75
+ - `credential [Yardi::Parameter::Credential]`
76
+ information needed to authenticate with Yardi
77
+ - `lead_source [String]` what Yardi calls TransactionSource
78
+ - `reason [String]` what Yardi calls Event Reasons. This is the reason for
79
+ the event, e.g. price inquiry, tour, etc.
80
+ - `property [Yardi::Parameter::Property]` the property to associate the guest
81
+ card with
82
+ - `user [Yardi::Parameter::User]` the user to associate the guest card with
79
83
 
80
84
  #### Yardi::Request::GetResidents
85
+
81
86
  Get all the residents for a given property ID.
82
87
 
83
88
  ##### Initialization parameters
84
89
 
85
- * `credential [Yardi::Parameter::Credential]` information needed to authenticate with Yardi
86
- * `property_id [String]` the remote `YardiPropertyId`
90
+ - `credential [Yardi::Parameter::Credential]` information needed to authenticate with Yardi
91
+ - `property_id [String]` the remote `YardiPropertyId`
87
92
 
88
93
  ##### Response
94
+
89
95
  An array of `Yardi::Model::Resident`s
90
96
 
91
97
  ###### Example
98
+
92
99
  ```ruby
93
100
  Yardi::Request::GetResidents.new(
94
101
  credential: credential, params: { property_id: 'p263656'}
@@ -140,20 +147,22 @@ Get a list of `Yardi::Model::Prospect`s for a given Prospect at the specified pr
140
147
 
141
148
  ##### Initialization parameters
142
149
 
143
- * `credential [Yardi::Parameter::Credential]` information needed to authenticate with Yardi
144
- * `params [Hash]`
145
- * `property_id [String]`
146
- * `prospect [Yardi::Parameter::Prospect]`
150
+ - `credential [Yardi::Parameter::Credential]` information needed to authenticate with Yardi
151
+ - `params [Hash]`
152
+ - `property_id [String]`
153
+ - `prospect [Yardi::Parameter::Prospect]`
154
+ - `with_or [Yardi::Parameter::With_or]`
147
155
 
148
156
  ##### Response
149
157
 
150
158
  An array of `Yardi::Model::Prospect`s
151
159
 
152
160
  ###### Example
161
+
153
162
  ```ruby
154
163
  Yardi::Request::GetYardiGuestActivity.new(
155
164
  credential: credential,
156
- params: { property_id: 'p263656', prospect: prospect }
165
+ params: { property_id: 'p263656', prospect: prospect, with_or: with_or }
157
166
  ).perform
158
167
  # => [#<Yardi::Model::Prospect>, #<Yardi::Model::Prospect>]
159
168
  ```
@@ -162,21 +171,18 @@ Yardi::Request::GetYardiGuestActivity.new(
162
171
 
163
172
  ##### Attributes
164
173
 
165
- * `first_name` The `Prospect`'s first name according to Yardi's database
166
- * `last_name` The `Prospect`'s last name according to Yardi's database
167
- * `email` The `Prospect`'s email address according to Yardi's database
168
- * `phones` An Array of the `Prospect`'s phone numbers, or `nil` if there are none
169
- * `events` An Array of `Yardi::Model::Event` objects
170
- * `prospect_id` The `Prospect` id from Yardi's database e.g. `"p00003693"`
171
- * `tenant_id` The tenant id from Yardi's database e.g. `"t000456"`
174
+ - `first_name` The `Prospect`'s first name according to Yardi's database
175
+ - `last_name` The `Prospect`'s last name according to Yardi's database
176
+ - `email` The `Prospect`'s email address according to Yardi's database
177
+ - `phones` An Array of the `Prospect`'s phone numbers, or `nil` if there are none
178
+ - `events` An Array of `Yardi::Model::Event` objects
179
+ - `prospect_id` The `Prospect` id from Yardi's database e.g. `"p00003693"`
180
+ - `tenant_id` The tenant id from Yardi's database e.g. `"t000456"`
172
181
 
173
182
  ## Development
174
183
 
175
184
  To install this gem onto your local machine, run `bundle exec rake install`.
176
- To release a new version, update the version number in `version.rb`, and then
177
- run `bundle exec rake release` to create a git tag for the version, push git
178
- commits and tags, and push the `.gem` file to
179
- [rubygems.org](https://rubygems.org).
185
+ To release a new version, follow the instructions [here](https://github.com/apartmentlist/albacore#releasing).
180
186
 
181
187
  ## Contributing
182
188
 
@@ -184,8 +190,24 @@ If you are interested in contributing to this project, please review the
184
190
  [contribution guidelines](docs/contributing.md).
185
191
 
186
192
  ## Versions
193
+
194
+ - 4.10.3 Patch for NilClass when building prospect
195
+ - 4.10.2 Patch for send_prospect_events in validator
196
+ - 4.10.1 Patch for send_prospect_events default value
197
+ - 4.10.0 GetYardiGuestActivity uses send_prospect_events parameter
198
+ - 4.9.1 Bug fix for request using GetYardiGuestActivity_SearchWithOR which does not need prospect eventing
199
+ - 4.9.0 Fix to change get_soap_action to action and add phones to prospect params
200
+ - 4.8.4 GetYardiGuestActivity uses a with_or parameter
201
+ - 4.8.2 Update EmptyResponse validator to look for Envelope in Xml
202
+ - 4.8.1 Update document parser to look for Envelope in Xml
203
+ - 4.8.0 Add GetPropertyConfigurations request
204
+ - 4.6.10 Update pms_resident and pms_prospect: add unit_name, resident_id and move_in_report_type
205
+ - 4.6.0 Add Snowflake eventing for residents and prospects
206
+ - 4.2.0 Add ability to build xml to reactivate and update guestcards
207
+ - 4.1.1 Fix to change param name of action to guestcard_action
208
+ - 4.1.0 Add guestcard action to build xml for active or inactive guestcard
187
209
  - 4.0.0 Add handling for 404 errors and move ConnectionError to be a subclass of
188
- Yardi::Error::Base
210
+ Yardi::Error::Base
189
211
  - 3.1.2 Fix Prospect parsing to properly handle missing `Event` nodes
190
212
  - 3.1.1 Fix roommate parsing to properly extract roommate data from GetResidents response
191
213
  - 3.1.0 Add roommates to Resident Model and Parser
data/bin/console CHANGED
File without changes
@@ -25,6 +25,11 @@ module Yardi
25
25
  ].freeze
26
26
  private_constant :DEFAULT_VALIDATOR_CLASSES
27
27
 
28
+ def initialize(params)
29
+ @params = params
30
+ after_initialize(params)
31
+ end
32
+
28
33
  # @param xml [String] the XML response from the request
29
34
  # @return [Object] the parsed object(s) from the rsesponse
30
35
  # @raise [Yardi::Error::Base] if the response is invalid
@@ -35,17 +40,27 @@ module Yardi
35
40
  raise unparsable_xml_error(xml)
36
41
  end
37
42
 
43
+ return [] if test_data_not_found?(parsed)
44
+
38
45
  # This is a temporary code to be able to see what Yardi response
39
46
  # looks like when envelope is empty.
40
- if !parsed.empty? && parsed['soap:Envelope'].nil?
41
- raise Yardi::Error::UnparsableResponse.new(xml)
47
+ if !parsed.empty? && parsed['soap:Envelope'].nil? && parsed['Envelope'].nil?
48
+ if ((parsed['html'] || {})['head'] || {})['title']
49
+ raise Yardi::Error::ErrorResponse, parsed['html']['head']['title']
50
+ else
51
+ raise Yardi::Error::UnparsableResponse, xml
52
+ end
42
53
  end
43
54
 
44
55
  [*DEFAULT_VALIDATOR_CLASSES, *validator_classes].each do |klass|
45
- klass.new(action: action, parsed_response: parsed).validate!
56
+ klass.new(action: action, parsed_response: parsed, params: @params).validate!
46
57
  end
47
58
 
48
- parse_body(parsed['soap:Envelope']['soap:Body'])
59
+ if parsed['soap:Envelope']
60
+ parse_body(parsed['soap:Envelope']['soap:Body'])
61
+ else
62
+ parse_body(parsed['Envelope']['Body'])
63
+ end
49
64
  end
50
65
 
51
66
  private
@@ -58,11 +73,16 @@ module Yardi
58
73
  # into a Hash
59
74
  # @return [Object] the parsed object(s) from the rsesponse
60
75
  # @raise [Yardi::Error::Base] if the response is invalid
61
- def parse_body(body)
76
+ def parse_body(_body)
62
77
  raise NotImplementedError,
63
78
  "#{self.class.name} must implement #{__method__}"
64
79
  end
65
80
 
81
+ # implement this method if you need a callback in subclass after it is initialized
82
+ def after_initialize(_params)
83
+ nil
84
+ end
85
+
66
86
  def action
67
87
  self.class::SOAP_ACTION
68
88
  end
@@ -80,6 +100,16 @@ module Yardi
80
100
  Yardi::Error::UnparsableResponse.new(response)
81
101
  end
82
102
  end
103
+
104
+ # If the requested test data file from Google Cloud Storage does not exist,
105
+ # the parsed response would be {}. In this case, we return an empty list.
106
+ def test_data_not_found?(parsed)
107
+ parsed.empty? && ( parser_name == 'Residents' || parser_name == 'Prospects' )
108
+ end
109
+
110
+ def parser_name
111
+ self.class.name.split('::').last
112
+ end
83
113
  end
84
114
  end
85
115
  end
@@ -64,7 +64,7 @@ module Yardi
64
64
  id_regex =
65
65
  /(Inserted|Updated) Prospect CustomerID: (?<remote_id>p\d+)/
66
66
  id_match = id_message['__content__'].match(id_regex)
67
- !id_match.nil? ? id_match[:remote_id] : nil
67
+ id_match.nil? ? nil : id_match[:remote_id]
68
68
  end
69
69
  end
70
70
  end
@@ -0,0 +1,39 @@
1
+ require_relative 'base'
2
+
3
+ module Yardi
4
+ module DocumentParser
5
+ class Properties < Base
6
+ SOAP_ACTION = 'GetPropertyConfigurations'.freeze
7
+
8
+ private
9
+
10
+ attr_reader :body
11
+
12
+ # @param body [Hash<String, Object>] the body of the XML response parsed
13
+ # into a Hash
14
+ # @return [Array<Yardi::Model::Property>]
15
+ # @raise [Yardi::Error::Base] if the response is invalid
16
+ def parse_body(body)
17
+ @body = body
18
+ properties
19
+ end
20
+
21
+ def properties
22
+ path = %w[Properties Property]
23
+ results = [result_node.dig(*path)].flatten.compact
24
+
25
+ if results.empty?
26
+ raise Error::NoResults,
27
+ 'Failed to get property configurations'
28
+ end
29
+
30
+ results.map { |r| create_property_configuration(r) }
31
+ end
32
+
33
+ # Creates a Property object
34
+ def create_property_configuration(property)
35
+ Model::Property.new(property)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,13 +1,14 @@
1
1
  require_relative 'base'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
2
4
  require 'yardi/model/prospect'
3
5
  require 'yardi/utils/phone_parser'
6
+ require 'yardi/validator/prospect_eventing'
4
7
 
5
8
  module Yardi
6
9
  module DocumentParser
7
10
  # Build Prospect objects from prospect search response body.
8
11
  class Prospects < Base
9
- SOAP_ACTION = 'GetYardiGuestActivity_Search'.freeze
10
-
11
12
  private
12
13
 
13
14
  attr_reader :body
@@ -33,8 +34,8 @@ module Yardi
33
34
  events = prospect.dig('Events', 'Event') || []
34
35
 
35
36
  Model::Prospect.new(
36
- first_name: customer['Name']['FirstName'],
37
- last_name: customer['Name']['LastName'],
37
+ first_name: customer['Name']&.[]('FirstName'),
38
+ last_name: customer['Name']&.[]('LastName'),
38
39
  email: customer['Email'],
39
40
  phones: Utils::PhoneParser.parse(customer['Phone']),
40
41
  events: build_events(events),
@@ -59,7 +60,7 @@ module Yardi
59
60
  end
60
61
 
61
62
  def transaction_source(event_nodes)
62
- transaction_node = event_nodes.detect{ |e| e['TransactionSource'].present? }
63
+ transaction_node = event_nodes.detect { |e| e['TransactionSource'].present? }
63
64
  if transaction_node.nil?
64
65
  'None Given From Yardi'
65
66
  else
@@ -74,6 +75,23 @@ module Yardi
74
75
 
75
76
  desired_id_node['IDValue']
76
77
  end
78
+
79
+ def validator_classes
80
+ # since leadsender also goes through this flow we want to make this generic/extendable by checking send_prospect_events
81
+ if @params[:send_prospect_events]
82
+ [Validator::ProspectEventing]
83
+ else
84
+ []
85
+ end
86
+ end
87
+
88
+ def action
89
+ if @params[:with_or]
90
+ 'GetYardiGuestActivity_SearchWithOR'.freeze
91
+ else
92
+ 'GetYardiGuestActivity_Search'.freeze
93
+ end
94
+ end
77
95
  end
78
96
  end
79
97
  end