yield_star_client 0.1.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.
Files changed (75) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +3 -0
  4. data/Gemfile +4 -0
  5. data/README.md +38 -0
  6. data/Rakefile +17 -0
  7. data/lib/yield_star_client/amenity_methods.rb +77 -0
  8. data/lib/yield_star_client/client.rb +84 -0
  9. data/lib/yield_star_client/errors.rb +52 -0
  10. data/lib/yield_star_client/floor_plan_methods.rb +78 -0
  11. data/lib/yield_star_client/lease_term_rent_methods.rb +185 -0
  12. data/lib/yield_star_client/property_methods.rb +138 -0
  13. data/lib/yield_star_client/rent_methods.rb +179 -0
  14. data/lib/yield_star_client/unit_methods.rb +95 -0
  15. data/lib/yield_star_client/validations.rb +18 -0
  16. data/lib/yield_star_client/version.rb +3 -0
  17. data/lib/yield_star_client.rb +74 -0
  18. data/spec/fixtures/faults/authentication_fault.xml +15 -0
  19. data/spec/fixtures/faults/generic_fault.xml +9 -0
  20. data/spec/fixtures/faults/internal_error_fault.xml +15 -0
  21. data/spec/fixtures/faults/operation_fault.xml +15 -0
  22. data/spec/fixtures/get_available_units/multiple_floor_plans.xml +53 -0
  23. data/spec/fixtures/get_available_units/no_floor_plans.xml +11 -0
  24. data/spec/fixtures/get_available_units/single_floor_plan.xml +28 -0
  25. data/spec/fixtures/get_floor_plan/full_floor_plan.xml +19 -0
  26. data/spec/fixtures/get_floor_plan/simple_floor_plan.xml +14 -0
  27. data/spec/fixtures/get_floor_plan_amenities/multiple_amenities.xml +19 -0
  28. data/spec/fixtures/get_floor_plan_amenities/no_amenities.xml +10 -0
  29. data/spec/fixtures/get_floor_plan_amenities/single_amenity.xml +15 -0
  30. data/spec/fixtures/get_floor_plans/multiple_floor_plans.xml +28 -0
  31. data/spec/fixtures/get_floor_plans/no_floor_plan.xml +10 -0
  32. data/spec/fixtures/get_floor_plans/single_floor_plan.xml +15 -0
  33. data/spec/fixtures/get_lease_term_rent/multiple_rates.xml +41 -0
  34. data/spec/fixtures/get_lease_term_rent/no_rates.xml +13 -0
  35. data/spec/fixtures/get_lease_term_rent/single_rate.xml +21 -0
  36. data/spec/fixtures/get_lease_term_rent_plus/multiple_rates.xml +43 -0
  37. data/spec/fixtures/get_lease_term_rent_plus/no_rates.xml +14 -0
  38. data/spec/fixtures/get_lease_term_rent_plus/single_rate.xml +22 -0
  39. data/spec/fixtures/get_properties/multiple_properties.xml +38 -0
  40. data/spec/fixtures/get_properties/no_property.xml +10 -0
  41. data/spec/fixtures/get_properties/single_property.xml +14 -0
  42. data/spec/fixtures/get_property/full_property.xml +25 -0
  43. data/spec/fixtures/get_property/simple_property.xml +14 -0
  44. data/spec/fixtures/get_property_parameters/full_parameters.xml +38 -0
  45. data/spec/fixtures/get_property_parameters/no_parameters.xml +10 -0
  46. data/spec/fixtures/get_property_parameters/simple_parameters.xml +14 -0
  47. data/spec/fixtures/get_renewal_lease_term_rent/multiple_rates.xml +28 -0
  48. data/spec/fixtures/get_renewal_lease_term_rent/no_rates.xml +10 -0
  49. data/spec/fixtures/get_renewal_lease_term_rent/single_rate.xml +21 -0
  50. data/spec/fixtures/get_rent_summary/multiple_summaries.xml +41 -0
  51. data/spec/fixtures/get_rent_summary/no_summaries.xml +11 -0
  52. data/spec/fixtures/get_rent_summary/single_summary.xml +24 -0
  53. data/spec/fixtures/get_unit/full_unit.xml +22 -0
  54. data/spec/fixtures/get_unit/simple_unit.xml +16 -0
  55. data/spec/fixtures/get_unit_amenities/multiple_amenities.xml +20 -0
  56. data/spec/fixtures/get_unit_amenities/no_amenities.xml +11 -0
  57. data/spec/fixtures/get_unit_amenities/single_amenity.xml +15 -0
  58. data/spec/fixtures/get_units/multiple_units.xml +32 -0
  59. data/spec/fixtures/get_units/no_units.xml +10 -0
  60. data/spec/fixtures/get_units/single_unit.xml +16 -0
  61. data/spec/spec_helper.rb +16 -0
  62. data/spec/support/fault_handler_shared_examples.rb +68 -0
  63. data/spec/support/validator_shared_examples.rb +79 -0
  64. data/spec/yield_star_client/amenity_methods_spec.rb +165 -0
  65. data/spec/yield_star_client/client_spec.rb +150 -0
  66. data/spec/yield_star_client/errors_spec.rb +93 -0
  67. data/spec/yield_star_client/floor_plan_methods_spec.rb +126 -0
  68. data/spec/yield_star_client/lease_term_rent_methods_spec.rb +391 -0
  69. data/spec/yield_star_client/property_methods_spec.rb +189 -0
  70. data/spec/yield_star_client/rent_methods_spec.rb +271 -0
  71. data/spec/yield_star_client/unit_methods_spec.rb +168 -0
  72. data/spec/yield_star_client/validations_spec.rb +19 -0
  73. data/spec/yield_star_client_spec.rb +89 -0
  74. data/yield_star_client.gemspec +34 -0
  75. metadata +348 -0
@@ -0,0 +1,138 @@
1
+ require 'yield_star_client/validations'
2
+ require 'modelish'
3
+
4
+ module YieldStarClient
5
+ # Represents a property in the YieldStar system.
6
+ #
7
+ # A property is guaranteed to have an +external_property_id+ and +name+; all other attributes are optional.
8
+ #
9
+ # @attr [String] external_property_id the property ID
10
+ # @attr [String] name the name of the property
11
+ # @attr [String] address the street address
12
+ # @attr [String] city the city in which the property is located
13
+ # @attr [String] state the two-letter code of the state in which the property is located
14
+ # @attr [String] zip the zip code
15
+ # @attr [String] fax the fax telephone number
16
+ # @attr [String] phone the voice telephone number
17
+ # @attr [Float] latitude the latitude of the property's location
18
+ # @attr [Float] longitude the longitude of the property's location
19
+ # @attr [Integer] unit_count the number of units at this property
20
+ # @attr [String] website the URL of the property website
21
+ # @attr [Integer] year_built the year in which the property was built
22
+ class Property < Modelish::Base
23
+ property :external_property_id
24
+ property :name
25
+ property :address
26
+ property :city
27
+ property :state
28
+ property :zip
29
+ property :fax
30
+ property :phone
31
+ property :latitude, :type => Float
32
+ property :longitude, :type => Float
33
+ property :unit_count, :type => Integer
34
+ property :website
35
+ property :year_built, :type => Integer
36
+ end
37
+
38
+ # Represents the pricing parameters for a particular property.
39
+ #
40
+ # This object is guaranteed to have an +external_property_id+; all other attributes may be nil.
41
+ #
42
+ # @attr [String] external_property_id the ID of the property
43
+ # @attr [Date] post_date the post date of the latest Price Optimizer forecasting and optimization nightly run.
44
+ # @attr [Integer] min_new_lease_term minimum length (in months) of a new lease term
45
+ # @attr [Integer] max_new_lease_term maximum length (in months) of a new lease term
46
+ # @attr [Integer] new_lease_term_options absolute number of lease term options to offer on either side of the base lease term when creating the lease term rent matrix.
47
+ # @attr [Integer] max_move_in_days number of fixed move in date options to return in response to a request for lease rates.
48
+ # @attr [Integer] min_renewal_lease_term minimum length (in months) of a renewal lease term
49
+ # @attr [Integer] max_renewal_lease_term maximum length (in months) of a renewal lease term
50
+ class PropertyParameters < Modelish::Base
51
+ property :external_property_id
52
+ property :post_date, :type => Date
53
+ property :min_new_lease_term, :type => Integer
54
+ property :max_new_lease_term, :type => Integer
55
+ property :new_lease_term_options, :type => Integer
56
+ property :max_move_in_days, :type => Integer
57
+ property :min_renewal_lease_term, :type => Integer
58
+ property :max_renewal_lease_term, :type => Integer
59
+ end
60
+
61
+ module PropertyMethods
62
+ include YieldStarClient::Validations
63
+
64
+ # Retrieves all properties for a client.
65
+ #
66
+ # @param [String] client_name the YieldStar client name
67
+ # @return [Array<YieldStarClient::Property>] list of properties
68
+ #
69
+ # @raise [ArgumentError] when client_name is missing or invalid
70
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
71
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
72
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
73
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
74
+ def get_properties(client_name)
75
+ validate_client_name!(client_name)
76
+
77
+ response = send_soap_request(:get_properties, :client_name => client_name)
78
+
79
+ props = response.to_hash[:get_properties_response][:return][:property] || []
80
+ props = [props].flatten
81
+ props.collect { |p| Property.new(p) }
82
+ end
83
+
84
+ # Retrieves information for a specific property.
85
+ #
86
+ # @param [String] client_name the name of the client to perform the request for
87
+ # @param [String] external_property_id the ID of the property to obtain information for
88
+ # @return [YieldStarClient::Property] the property data
89
+ #
90
+ # @raise [ArgumentError] when external_property_id or client_name are missing or invalid
91
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
92
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
93
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
94
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
95
+ def get_property(client_name, external_property_id)
96
+ validate_client_name!(client_name)
97
+ validate_external_property_id!(external_property_id)
98
+
99
+ response = send_soap_request(:get_property, :client_name => client_name, :external_property_id => external_property_id)
100
+
101
+ property = response.to_hash[:get_property_response][:return][:property]
102
+ Property.new(property)
103
+ end
104
+
105
+
106
+ # Retrieves pricing parameters for a specific property.
107
+ #
108
+ # @param [String] client_name the name of the client to perform the request for
109
+ # @param [String] external_property_id the ID of the property to obtain information for
110
+ # @return [YieldStarClient::PropertyParameters] the pricing data
111
+ #
112
+ # @raise [ArgumentError] when external_property_id or client_name are missing or invalid
113
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
114
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
115
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
116
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
117
+ def get_property_parameters(client_name, external_property_id)
118
+ validate_client_name!(client_name)
119
+ validate_external_property_id!(external_property_id)
120
+
121
+ response = send_soap_request(:get_property_parameters, :client_name => client_name,
122
+ :external_property_id => external_property_id)
123
+
124
+ response_hash = response.to_hash[:get_property_parameters_response][:return]
125
+ param_hash = { :external_property_id => response_hash[:external_property_id] }
126
+ params = [response_hash[:parameter]].flatten
127
+
128
+ unless params.first.nil?
129
+ params.each do |param|
130
+ name = param[:name].downcase.gsub(/(max|min)imum/, '\1').gsub(/\s+/, '_').to_sym
131
+ param_hash[name] = param[:value]
132
+ end
133
+ end
134
+
135
+ PropertyParameters.new(param_hash)
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,179 @@
1
+ require 'yield_star_client/validations'
2
+ require 'modelish'
3
+
4
+ module YieldStarClient
5
+ # Represents a summary of rent information for a floor plan/unit type combination.
6
+ #
7
+ # @attr [Date] effective_date the data on which all listed prices are considered effective
8
+ # @attr [String] external_property_id the ID of the property associated with the floor plan
9
+ # @attr [String] floor_plan_name the floor plan that matches the Price Optimizer dashboard
10
+ # @attr [String] unit_type the unit type for this information
11
+ # @attr [Float] bedrooms the number of bedrooms in this unit type
12
+ # @attr [Float] bathrooms the number of bathrooms in this unit type
13
+ # @attr [Integer] avg_square_feet the average square footage in this unit type
14
+ # @attr [Integer] min_market_rent the minimum market rents for the currently available units
15
+ # in this unit type
16
+ # @attr [Integer] max_market_rent the maximum market rents for the currently available units
17
+ # in this unit type
18
+ # @attr [Object] concession_type reserved for future use by YieldStar
19
+ # @attr [Integer] min_concession the minimum value of any ocncessions (rent discount,
20
+ # recurrent discounts currently being offtered) for
21
+ # this particular unit type
22
+ # @attr [Integer] max_concession the maximum value of any concessions (rent discounts,
23
+ # recurrent discounts currently being offered) for this
24
+ # particular unit type
25
+ # @attr [Integer] min_final_rent the minimum **EFFECTIVE** rents for the currently available
26
+ # units in this unit type
27
+ # @attr [Integer] max_final_rent the maximum **EFFECTIVE** rents for the currently available
28
+ # units in this unit type.
29
+ # @attr [String] floor_plan_description the marketing name of the floor plan
30
+ class RentSummary < Modelish::Base
31
+ property :effective_date, :type => Date
32
+ property :external_property_id
33
+ property :floor_plan_name
34
+ property :unit_type
35
+ property :bedrooms, :type => Float, :from => :bed_rooms
36
+ property :bathrooms, :type => Float, :from => :bath_rooms
37
+ property :avg_square_feet, :type => Integer, :from => :avg_sq_ft
38
+ property :min_market_rent, :type => Integer
39
+ property :max_market_rent, :type => Integer
40
+ property :concession_type
41
+ property :min_concession, :type => Integer
42
+ property :max_concession, :type => Integer
43
+ property :min_final_rent, :type => Integer
44
+ property :max_final_rent, :type => Integer
45
+ property :floor_plan_description
46
+ end
47
+
48
+ # Represents a floor plan with available units.
49
+ #
50
+ # @attr [String] external_property_id the ID of the property associated with the
51
+ # floor plan
52
+ # @attr [Date] effective_date the date that all listed prices are considered effective
53
+ # @attr [String] floor_plan_name the name of the floor plan that matches the
54
+ # Price Optimizer dashboard
55
+ # @attr [Array<AvailableUnit>] units the available unit data associated with this
56
+ # floor plan
57
+ # @attr [Float] bedrooms the number of bedrooms in this floor plan
58
+ # @attr [Float] bathrooms the number of bathrooms in this floor plan
59
+ # @attr [Integer] square_feet the square footage of the floor plan
60
+ class AvailableFloorPlan < Modelish::Base
61
+ property :external_property_id
62
+ property :effective_date, :type => Date
63
+ property :floor_plan_name
64
+ property :bedrooms, :type => Float, :from => :bed_rooms
65
+ property :bathrooms, :type => Float, :from => :bath_rooms
66
+ property :square_feet, :type => Integer, :from => :sq_ft
67
+ property :units, :from => :unit, :default => []
68
+
69
+ def initialize(options = {})
70
+ super(options)
71
+
72
+ # TODO: add support for nested types to modelish?
73
+ self.units = [self.units].flatten.collect { |u| AvailableUnit.new(u) }
74
+ end
75
+ end
76
+
77
+ # Represents an available unit.
78
+ #
79
+ # @attr [String] building the building for this unit
80
+ # @attr [String] unit_type the unit type
81
+ # @attr [String] unit_number the unit number from the property management system
82
+ # @attr [Array<String>] features the list of unit amenities/features
83
+ # @attr [Symbol] status the availability status of this unit. The status may be one of the
84
+ # following values:
85
+ # * +:on_notice+
86
+ # * +:vacant+
87
+ # * +:new_unit+
88
+ # * +:unknown+
89
+ # @attr [Date] date_available the date this unit can be occupied
90
+ # @attr [Integer] base_market_rent the 12-month market rent
91
+ # @attr [Integer] base_concession the concession amountt
92
+ # @attr [Integer] base_final_rent the 12-month effective rent (market rent less concessions)
93
+ # @attr [Integer] best_lease_term the lease term associated with the best price from
94
+ # the Lease Term Rent Matrix.
95
+ # @attr [Integer] best_market_rent the market monthly rent associated with the best price
96
+ # term and move-in period
97
+ # @attr [Integer] best_concession the concession associated with the best price term
98
+ # and move-in period
99
+ # @attr [Integer] best_final_rent the effective monthly rent associated with the best
100
+ # price term and move-in period
101
+ class AvailableUnit < Modelish::Base
102
+ property :building
103
+ property :unit_type
104
+ property :unit_number
105
+ property :features, :type => Array, :default => [], :from => :feature
106
+ property :status, :type => Symbol
107
+ property :date_available, :type => Date
108
+ property :base_market_rent, :type => Integer
109
+ property :base_concession, :type => Integer
110
+ property :base_final_rent, :type => Integer
111
+ property :best_lease_term, :type => Integer
112
+ property :best_market_rent, :type => Integer
113
+ property :best_concession, :type => Integer
114
+ property :best_final_rent, :type => Integer
115
+ end
116
+
117
+ module RentMethods
118
+ # Retrieves high-level rent information for all currently available floor
119
+ # plans within a specific property.
120
+ #
121
+ # @param [String] client_name the YieldStar client name
122
+ # @param [String] external_property_id the ID of the property associated
123
+ # with the requested data
124
+ #
125
+ # @return [Array<YieldStarClient::RentSummary>]
126
+ #
127
+ # @raise [ArgumentError] when a required argument is missing or invalid
128
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
129
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
130
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
131
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
132
+ def get_rent_summary(client_name, external_property_id)
133
+ validate_client_name!(client_name)
134
+ validate_external_property_id!(external_property_id)
135
+
136
+ response = send_soap_request(:get_rent_summary, :client_name => client_name,
137
+ :external_property_id => external_property_id)
138
+
139
+ data = response.to_hash[:get_rent_summary_response][:return]
140
+ shared_props = {:external_property_id => data[:external_property_id],
141
+ :effective_date => data[:effective_date]}
142
+ summaries = []
143
+ summaries << data[:floor_plan_unit_type] if data[:floor_plan_unit_type]
144
+
145
+ summaries.flatten.collect { |s| RentSummary.new(shared_props.merge(s)) }
146
+ end
147
+
148
+ # Retrieves rental information for all currently available units at a specific
149
+ # property, grouped by floor plan.
150
+ #
151
+ # @param [String] client_name the YieldStar client name
152
+ # @param [String] external_property_id the ID of the property where the available
153
+ # units are located
154
+ #
155
+ # @return [Array<YieldStarClient::AvailableFloorPlan>] list of floor plans with
156
+ # available units
157
+ #
158
+ # @raise [ArgumentError] when a required argument is missing or invalid
159
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
160
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
161
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
162
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
163
+ def get_available_units(client_name, external_property_id)
164
+ validate_client_name!(client_name)
165
+ validate_external_property_id!(external_property_id)
166
+
167
+ response = send_soap_request(:get_available_units, :client_name => client_name,
168
+ :external_property_id => external_property_id)
169
+
170
+ data = response.to_hash[:get_available_units_response][:return]
171
+ base_props = data.reject { |k,v| ![:external_property_id, :effective_date].include?(k) }
172
+
173
+ floor_plans = []
174
+ floor_plans << data[:floor_plan] if data[:floor_plan]
175
+
176
+ floor_plans.flatten.collect { |fp| AvailableFloorPlan.new(base_props.merge(fp)) }
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,95 @@
1
+ require 'yield_star_client/validations'
2
+ require 'modelish'
3
+
4
+ module YieldStarClient
5
+ # Represents a unit in the YieldStar system.
6
+ #
7
+ # A unit is guaranteed to have an +external_property_id+, +floor_plan_name+, +name+, and +availablity_status+.
8
+ # All other attributes are optional.
9
+ #
10
+ # @attr [String] external_property_id the property ID
11
+ # @attr [String] floor_plan_name the name of the unit's floor plan
12
+ # @attr [String] name the unit name
13
+ # @attr [Symbol] availability_status the current availability of the unit. This may be one of the following values:
14
+ # * +:occupied+ -- this unit is presently leased by a resident
15
+ # * +:occupied_on_notice+ -- this unit is presently leased by a resident but a notice date has been provided
16
+ # * +:vacant+ -- this unit is not presently leased
17
+ # * +:pending+ -- this unit is available but a lease is pending
18
+ # * +:unknown+ -- the status is unknown or unrecognized
19
+ # @attr [String] building the name of the building associated with the unit
20
+ # @attr [Float] bedrooms the number of bedrooms in the unit
21
+ # @attr [Float] bathrooms the number of bathrooms in the unit
22
+ # @attr [Integer] square_feet the square footage of the unit
23
+ # @attr [String] unit_type the client-defined grouping of the unit
24
+ # @attr [Date] make_ready_date the date on which the unit is ready for move-in
25
+ class Unit < Modelish::Base
26
+ property :external_property_id
27
+ property :floor_plan_name
28
+ property :name
29
+ property :availability_status, :type => Symbol
30
+ property :building
31
+ property :bedrooms, :from => :bed_rooms, :type => Float
32
+ property :bathrooms, :from => :bath_rooms, :type => Float
33
+ property :square_feet, :type => Integer, :from => :square_footage
34
+ property :unit_type
35
+ property :make_ready_date, :type => Date
36
+ end
37
+
38
+ module UnitMethods
39
+ include Validations
40
+ # Retrieves data about a specific unit.
41
+ #
42
+ # @param [String] client_name the YieldStar client name
43
+ # @param [String] external_property_id the ID of the property where the unit is located
44
+ # @param [String] unit_name the name of the unit to retrieve
45
+ # @param [optional,String] building_name the name of the building in which the unit is located
46
+ #
47
+ # @return [YieldStarClient::Unit] the unit data
48
+ #
49
+ # @raise [ArgumentError] when a required argument is missing or invalid
50
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
51
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
52
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
53
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
54
+ def get_unit(client_name, external_property_id, unit_name, building_name=nil)
55
+ validate_client_name!(client_name)
56
+ validate_external_property_id!(external_property_id)
57
+ validate_required!(:unit_name => unit_name)
58
+
59
+ body = {:client_name => client_name, :external_property_id => external_property_id, :name => unit_name}
60
+ body[:building] = building_name if building_name
61
+
62
+ response = send_soap_request(:get_unit, body)
63
+ unit = response.to_hash[:get_unit_response][:return][:unit]
64
+
65
+ Unit.new(unit)
66
+ end
67
+
68
+ # Retrieves all units for a specific property, optionally filtered by floor plan.
69
+ #
70
+ # @param [String] client_name the YieldStar client name
71
+ # @param [String] external_property_id the ID of the property where the units are located
72
+ # @param [optional,String] floor_plan_name the name of the floor plan associated with the units
73
+ #
74
+ # @return [Array<Unit>] a list of unit data
75
+ #
76
+ # @raise [ArgumentError] when a required argument is missing or invalid
77
+ # @raise [YieldStarClient::AuthenticationError] when unable to authenticate to the web service
78
+ # @raise [YieldStarClient::OperationError] when the service raises an OperationError fault
79
+ # @raise [YieldStarClient::InternalError] when the service raises an InternalError fault
80
+ # @raise [YieldStarClient::ServerError] when any other server-side error occurs
81
+ def get_units(client_name, external_property_id, floor_plan_name=nil)
82
+ validate_client_name!(client_name)
83
+ validate_external_property_id!(external_property_id)
84
+
85
+ body = {:client_name => client_name, :external_property_id => external_property_id}
86
+ body[:floor_plan_name] = floor_plan_name if floor_plan_name
87
+ response = send_soap_request(:get_units, body)
88
+
89
+ units = response.to_hash[:get_units_response][:return][:unit] || []
90
+ units = [units].flatten
91
+
92
+ units.collect { |u| Unit.new(u) }
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,18 @@
1
+ require 'modelish'
2
+
3
+ module YieldStarClient
4
+ # @private
5
+ module Validations
6
+ include Modelish::Validations::ClassMethods
7
+
8
+ def validate_client_name!(client_name)
9
+ validate_required!(:client_name => client_name)
10
+ validate_length!(:client_name, client_name, 16)
11
+ end
12
+
13
+ def validate_external_property_id!(external_property_id)
14
+ validate_required!(:external_property_id => external_property_id)
15
+ validate_length!(:external_property_id, external_property_id, 50)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module YieldStarClient
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,74 @@
1
+ $:.unshift(File.expand_path('yield_star_client',File.dirname(__FILE__)))
2
+
3
+ module YieldStarClient
4
+ autoload :Configlet, 'configlet'
5
+ extend Configlet
6
+
7
+ # All valid configuration options.
8
+ #
9
+ # @see YieldStarClient.configure
10
+ VALID_CONFIG_OPTIONS = [:endpoint, :username, :password, :namespace]
11
+
12
+ DEFAULT_ENDPOINT = 'https://rmsws.yieldstar.com/rmsws/AppExchange'
13
+ DEFAULT_NAMESPACE = 'http://yieldstar.com/ws/AppExchange/v1'
14
+
15
+ # Default configuration - happens whether or not .configure is called
16
+ config :yield_star do
17
+ default :endpoint => DEFAULT_ENDPOINT
18
+ default :namespace => DEFAULT_NAMESPACE
19
+ end
20
+
21
+ # Mutators and accessors for configuration options
22
+ class << self
23
+ VALID_CONFIG_OPTIONS.each do |config_opt|
24
+ define_method(config_opt) do
25
+ YieldStarClient[config_opt]
26
+ end
27
+
28
+ define_method("#{config_opt}=".to_sym) do |val|
29
+ YieldStarClient[config_opt] = val
30
+ end
31
+ end
32
+ end
33
+
34
+ # Configures this module through the given +block+.
35
+ # Default configuration options will be applied unless
36
+ # they are explicitly overridden in the +block+.
37
+ #
38
+ # @yield [_self] configures service connection options
39
+ # @yieldparam [YieldstarClient] _self the object on which the configure method was called
40
+ # @example Typical case utilizing defaults
41
+ # YieldStarClient.configure do |config|
42
+ # config.username = 'my_user'
43
+ # config.password = 'my_pass'
44
+ # end
45
+ # @example Overriding defaults
46
+ # YieldStarClient.configure do |config|
47
+ # config.username = 'my_user'
48
+ # config.password = 'my_pass'
49
+ # config.endpoint = 'http://my.endpoint.com'
50
+ # config.namespace = 'http://my.namespace.com'
51
+ # end
52
+ # @return [YieldStarClient] _self
53
+ # @see VALID_CONFIG_OPTIONS
54
+ def self.configure
55
+ config :yield_star do
56
+ yield self
57
+ end
58
+
59
+ self
60
+ end
61
+
62
+ # Resets this module's configuration.
63
+ # Configuration options will be set to default values
64
+ # if they exist; otherwise, they will be set to nil.
65
+ #
66
+ # @see VALID_CONFIG_OPTIONS
67
+ # @see DEFAULT_ENDPOINT
68
+ # @see DEFAULT_NAMESPACE
69
+ def self.reset
70
+ VALID_CONFIG_OPTIONS.each { |opt| self.send("#{opt}=", nil) }
71
+ end
72
+
73
+ require 'client'
74
+ end
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
5
+ <faultcode>S:Server</faultcode>
6
+ <faultstring>Client [foo] not found for this user [12e7e719764-21c]</faultstring>
7
+ <detail>
8
+ <AuthenticationFault:AuthenticationFault xmlns:AuthenticationFault="http://yieldstar.com/ws/AppExchange/v1" xmlns="http://yieldstar.com/ws/AppExchange/v1">
9
+ <code>12e7e719764-21c</code>
10
+ <message>Client [foo] not found for this user [12e7e719764-21c]</message>
11
+ </AuthenticationFault:AuthenticationFault>
12
+ </detail>
13
+ </S:Fault>
14
+ </S:Body>
15
+ </S:Envelope>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <S:Fault xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
5
+ <faultcode>S:Server</faultcode>
6
+ <faultstring>java.lang.NullPointerException</faultstring>
7
+ </S:Fault>
8
+ </S:Body>
9
+ </S:Envelope>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
5
+ <faultcode>S:Server</faultcode>
6
+ <faultstring>Internal error [12e7cfbb782-37a]</faultstring>
7
+ <detail>
8
+ <InternalErrorFault:InternalErrorFault xmlns:InternalErrorFault="http://yieldstar.com/ws/AppExchange/v1" xmlns="http://yieldstar.com/ws/AppExchange/v1">
9
+ <code>12e7cfbb782-37a</code>
10
+ <message>Internal error [12e7cfbb782-37a]</message>
11
+ </InternalErrorFault:InternalErrorFault>
12
+ </detail>
13
+ </S:Fault>
14
+ </S:Body>
15
+ </S:Envelope>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
5
+ <faultcode>S:Server</faultcode>
6
+ <faultstring>Invalid floor plan name null [12e7e6acc24-1b]</faultstring>
7
+ <detail>
8
+ <OperationFault:OperationFault xmlns:OperationFault="http://yieldstar.com/ws/AppExchange/v1" xmlns="http://yieldstar.com/ws/AppExchange/v1">
9
+ <code>12e7e6acc24-1b</code>
10
+ <message>Invalid floor plan name null [12e7e6acc24-1b]</message>
11
+ </OperationFault:OperationFault>
12
+ </detail>
13
+ </S:Fault>
14
+ </S:Body>
15
+ </S:Envelope>
@@ -0,0 +1,53 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <getAvailableUnitsResponse xmlns="http://yieldstar.com/ws/AppExchange/v1">
5
+ <return>
6
+ <externalPropertyId>42</externalPropertyId>
7
+ <effectiveDate>2011-03-15</effectiveDate>
8
+ <floorPlan>
9
+ <floorPlanName>1B1B-D</floorPlanName>
10
+ <bedRooms>1.0</bedRooms>
11
+ <bathRooms>1.0</bathRooms>
12
+ <sqFt>874</sqFt>
13
+ </floorPlan>
14
+ <floorPlan>
15
+ <floorPlanName>1B1B</floorPlanName>
16
+ <unit>
17
+ <building>99</building>
18
+ <unitType>1b1ba-r</unitType>
19
+ <unitNumber>11235</unitNumber>
20
+ <feature>50 Base Rent Adjustment</feature>
21
+ <feature>2nd Floor</feature>
22
+ <status>NewUnit</status>
23
+ <dateAvailable>2011-05-11</dateAvailable>
24
+ <baseMarketRent>710</baseMarketRent>
25
+ <baseConcession>500</baseConcession>
26
+ <baseFinalRent>669</baseFinalRent>
27
+ <bestLeaseTerm>15</bestLeaseTerm>
28
+ <bestMarketRent>699</bestMarketRent>
29
+ <bestConcession>625</bestConcession>
30
+ <bestFinalRent>658</bestFinalRent>
31
+ </unit>
32
+ <unit>
33
+ <unitType>1b1ba</unitType>
34
+ <unitNumber>81321</unitNumber>
35
+ <feature>1st floor</feature>
36
+ <status>Vacant</status>
37
+ <dateAvailable>2011-03-07</dateAvailable>
38
+ <baseMarketRent>732</baseMarketRent>
39
+ <baseConcession>500</baseConcession>
40
+ <baseFinalRent>690</baseFinalRent>
41
+ <bestLeaseTerm>15</bestLeaseTerm>
42
+ <bestMarketRent>719</bestMarketRent>
43
+ <bestConcession>625</bestConcession>
44
+ <bestFinalRent>678</bestFinalRent>
45
+ </unit>
46
+ <bedRooms>1.0</bedRooms>
47
+ <bathRooms>1.0</bathRooms>
48
+ <sqFt>666</sqFt>
49
+ </floorPlan>
50
+ </return>
51
+ </getAvailableUnitsResponse>
52
+ </S:Body>
53
+ </S:Envelope>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <getAvailableUnitsResponse xmlns="http://yieldstar.com/ws/AppExchange/v1">
5
+ <return>
6
+ <externalPropertyId>1509</externalPropertyId>
7
+ <effectiveDate>2011-03-13</effectiveDate>
8
+ </return>
9
+ </getAvailableUnitsResponse>
10
+ </S:Body>
11
+ </S:Envelope>
@@ -0,0 +1,28 @@
1
+ <?xml version="1.0"?>
2
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
3
+ <S:Body>
4
+ <getAvailableUnitsResponse xmlns="http://yieldstar.com/ws/AppExchange/v1">
5
+ <return>
6
+ <externalPropertyId>42</externalPropertyId>
7
+ <effectiveDate>2011-03-13</effectiveDate>
8
+ <floorPlan>
9
+ <floorPlanName>my_floor_plan</floorPlanName>
10
+ <unit>
11
+ <unitType>2b2ba</unitType>
12
+ <unitNumber>112358</unitNumber>
13
+ <status>OnNotice</status>
14
+ <dateAvailable>2011-04-01</dateAvailable>
15
+ <baseFinalRent>1054</baseFinalRent>
16
+ <bestLeaseTerm>14</bestLeaseTerm>
17
+ <bestMarketRent>1079</bestMarketRent>
18
+ <bestConcession>583</bestConcession>
19
+ <bestFinalRent>1038</bestFinalRent>
20
+ </unit>
21
+ <bedRooms>2.0</bedRooms>
22
+ <bathRooms>2.0</bathRooms>
23
+ <sqFt>1161</sqFt>
24
+ </floorPlan>
25
+ </return>
26
+ </getAvailableUnitsResponse>
27
+ </S:Body>
28
+ </S:Envelope>