xero-ruby 3.14.0 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 221baaa300a1c4fb1c743c8abd998b3e17b869e3306e1e7871baa5531ed3e811
4
- data.tar.gz: '08e1837f06c9caff147daa7437f7033a62374bfcd3b9a0cbd282be74612b3fc5'
3
+ metadata.gz: a7cf036e746cf06c49d997cee30a28ca8e74cb022bf90c3ea5fdb62d2cdeb7d5
4
+ data.tar.gz: 3129b96cedce8ac8a3ba3da37ab261111f468b17a898050f9501753a33b99663
5
5
  SHA512:
6
- metadata.gz: c0021ba79888c37bf7b59f5e886828b77e948a319ce83014269859ffd4d95cab3016a716de93bbcaa47369d067035d687c62d7ede8d74a3e99524a3ddba4b652
7
- data.tar.gz: b4777d82730c8f659ca79726a707a01dba12895752664a433c6a55fe0301cfbad768843f875b07e08c584a82c68caecca93f20af2d9136ff2eb3fdcdc361f0f5
6
+ metadata.gz: 166a4fcfaf12b575d8d49b2cc946e4bf640286348e935ae1db2a269a9466d42b101d4f5ac32a2dde234e12b8fd6bf9652988156eda75cff4f4f7e2c835a36628
7
+ data.tar.gz: 3edd6d7e65437d1133601ab0a91d94db00817ce5e6c9aad74282a5d75982427a1addc464c0106f82150d12e6ecb5e2b40f8f337296faf4173c012af912556d94
data/README.md CHANGED
@@ -175,7 +175,7 @@ xero_app_store_client ||= XeroRuby::ApiClient.new(credentials: {
175
175
  client_id: ENV['CLIENT_ID'],
176
176
  client_secret: ENV['CLIENT_SECRET'],
177
177
  grant_type: 'client_credentials'
178
- scopes: ['marketplace.billing']
178
+ scopes: 'marketplace.billing openid profile email'
179
179
  })
180
180
 
181
181
  xero_app_store_client.get_client_credentials_token
@@ -83,5 +83,243 @@ module XeroRuby
83
83
  end
84
84
  return data, status_code, headers
85
85
  end
86
+
87
+ # Gets all usage records related to the subscription
88
+ # @param subscription_id [String] Unique identifier for Subscription object
89
+ # @param [Hash] opts the optional parameters
90
+ # @return [UsageRecordsList]
91
+ def get_usage_records(subscription_id, opts = {})
92
+ data, _status_code, _headers = get_usage_records_with_http_info(subscription_id, opts)
93
+ data
94
+ end
95
+
96
+ # Gets all usage records related to the subscription
97
+ # @param subscription_id [String] Unique identifier for Subscription object
98
+ # @param [Hash] opts the optional parameters
99
+ # @return [Array<(UsageRecordsList, Integer, Hash)>] UsageRecordsList data, response status code and response headers
100
+ def get_usage_records_with_http_info(subscription_id, options = {})
101
+ opts = options.dup
102
+ if @api_client.config.debugging
103
+ @api_client.config.logger.debug 'Calling API: AppStoreApi.get_usage_records ...'
104
+ end
105
+ # verify the required parameter 'subscription_id' is set
106
+ if @api_client.config.client_side_validation && subscription_id.nil?
107
+ fail ArgumentError, "Missing the required parameter 'subscription_id' when calling AppStoreApi.get_usage_records"
108
+ end
109
+ # resource path
110
+ local_var_path = '/subscriptions/{subscriptionId}/usage-records'.sub('{' + 'subscriptionId' + '}', subscription_id.to_s)
111
+
112
+ # camelize keys of incoming `where` opts
113
+ opts[:'where'] = @api_client.parameterize_where(opts[:'where']) if !opts[:'where'].nil?
114
+
115
+ # query parameters
116
+ query_params = opts[:query_params] || {}
117
+
118
+ # XeroAPI's `IDs` convention openapi-generator does not snake_case properly.. manual over-riding `i_ds` malformations:
119
+ query_params[:'IDs'] = @api_client.build_collection_param(opts[:'ids'], :csv) if !opts[:'ids'].nil?
120
+ query_params[:'ContactIDs'] = @api_client.build_collection_param(opts[:'contact_ids'], :csv) if !opts[:'contact_ids'].nil?
121
+
122
+ # header parameters
123
+ header_params = opts[:header_params] || {}
124
+ # HTTP header 'Accept' (if needed)
125
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
126
+
127
+ # form parameters
128
+ form_params = opts[:form_params] || {}
129
+
130
+ # http body (model)
131
+ post_body = opts[:body]
132
+
133
+ # return_type
134
+ return_type = opts[:return_type] || 'UsageRecordsList'
135
+
136
+ # auth_names
137
+ auth_names = opts[:auth_names] || ['OAuth2']
138
+
139
+ new_options = opts.merge(
140
+ :header_params => header_params,
141
+ :query_params => query_params,
142
+ :form_params => form_params,
143
+ :body => post_body,
144
+ :auth_names => auth_names,
145
+ :return_type => return_type
146
+ )
147
+
148
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, "AppStoreApi", new_options)
149
+ if @api_client.config.debugging
150
+ @api_client.config.logger.debug "API called: AppStoreApi#get_usage_records\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
151
+ end
152
+ return data, status_code, headers
153
+ end
154
+
155
+ # Send metered usage belonging to this subscription and subscription item
156
+ # @param subscription_id [String] Unique identifier for Subscription object
157
+ # @param subscription_item_id [String] The unique identifier of the subscriptionItem
158
+ # @param create_usage_record [CreateUsageRecord] Contains the quantity for the usage record to create
159
+ # @param [Hash] opts the optional parameters
160
+ # @return [UsageRecord]
161
+ def post_usage_records(subscription_id, subscription_item_id, create_usage_record, opts = {})
162
+ data, _status_code, _headers = post_usage_records_with_http_info(subscription_id, subscription_item_id, create_usage_record, opts)
163
+ data
164
+ end
165
+
166
+ # Send metered usage belonging to this subscription and subscription item
167
+ # @param subscription_id [String] Unique identifier for Subscription object
168
+ # @param subscription_item_id [String] The unique identifier of the subscriptionItem
169
+ # @param create_usage_record [CreateUsageRecord] Contains the quantity for the usage record to create
170
+ # @param [Hash] opts the optional parameters
171
+ # @return [Array<(UsageRecord, Integer, Hash)>] UsageRecord data, response status code and response headers
172
+ def post_usage_records_with_http_info(subscription_id, subscription_item_id, create_usage_record, options = {})
173
+ opts = options.dup
174
+ if @api_client.config.debugging
175
+ @api_client.config.logger.debug 'Calling API: AppStoreApi.post_usage_records ...'
176
+ end
177
+ # verify the required parameter 'subscription_id' is set
178
+ if @api_client.config.client_side_validation && subscription_id.nil?
179
+ fail ArgumentError, "Missing the required parameter 'subscription_id' when calling AppStoreApi.post_usage_records"
180
+ end
181
+ # verify the required parameter 'subscription_item_id' is set
182
+ if @api_client.config.client_side_validation && subscription_item_id.nil?
183
+ fail ArgumentError, "Missing the required parameter 'subscription_item_id' when calling AppStoreApi.post_usage_records"
184
+ end
185
+ # verify the required parameter 'create_usage_record' is set
186
+ if @api_client.config.client_side_validation && create_usage_record.nil?
187
+ fail ArgumentError, "Missing the required parameter 'create_usage_record' when calling AppStoreApi.post_usage_records"
188
+ end
189
+ # resource path
190
+ local_var_path = '/subscriptions/{subscriptionId}/items/{subscriptionItemId}/usage-records'.sub('{' + 'subscriptionId' + '}', subscription_id.to_s).sub('{' + 'subscriptionItemId' + '}', subscription_item_id.to_s)
191
+
192
+ # camelize keys of incoming `where` opts
193
+ opts[:'where'] = @api_client.parameterize_where(opts[:'where']) if !opts[:'where'].nil?
194
+
195
+ # query parameters
196
+ query_params = opts[:query_params] || {}
197
+
198
+ # XeroAPI's `IDs` convention openapi-generator does not snake_case properly.. manual over-riding `i_ds` malformations:
199
+ query_params[:'IDs'] = @api_client.build_collection_param(opts[:'ids'], :csv) if !opts[:'ids'].nil?
200
+ query_params[:'ContactIDs'] = @api_client.build_collection_param(opts[:'contact_ids'], :csv) if !opts[:'contact_ids'].nil?
201
+
202
+ # header parameters
203
+ header_params = opts[:header_params] || {}
204
+ # HTTP header 'Accept' (if needed)
205
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
206
+ # HTTP header 'Content-Type'
207
+ header_params['Content-Type'] = @api_client.select_header_content_type(['application/json'])
208
+
209
+ # form parameters
210
+ form_params = opts[:form_params] || {}
211
+
212
+ # http body (model)
213
+ post_body = opts[:body] || @api_client.object_to_http_body(create_usage_record)
214
+
215
+ # return_type
216
+ return_type = opts[:return_type] || 'UsageRecord'
217
+
218
+ # auth_names
219
+ auth_names = opts[:auth_names] || ['OAuth2']
220
+
221
+ new_options = opts.merge(
222
+ :header_params => header_params,
223
+ :query_params => query_params,
224
+ :form_params => form_params,
225
+ :body => post_body,
226
+ :auth_names => auth_names,
227
+ :return_type => return_type
228
+ )
229
+
230
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, "AppStoreApi", new_options)
231
+ if @api_client.config.debugging
232
+ @api_client.config.logger.debug "API called: AppStoreApi#post_usage_records\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
233
+ end
234
+ return data, status_code, headers
235
+ end
236
+
237
+ # Update and existing metered usage belonging to this subscription and subscription item
238
+ # @param subscription_id [String] Unique identifier for Subscription object
239
+ # @param subscription_item_id [String] The unique identifier of the subscriptionItem
240
+ # @param usage_record_id [String] The unique identifier of the usage record
241
+ # @param update_usage_record [UpdateUsageRecord] Contains the quantity for the usage record to update
242
+ # @param [Hash] opts the optional parameters
243
+ # @return [UsageRecord]
244
+ def put_usage_records(subscription_id, subscription_item_id, usage_record_id, update_usage_record, opts = {})
245
+ data, _status_code, _headers = put_usage_records_with_http_info(subscription_id, subscription_item_id, usage_record_id, update_usage_record, opts)
246
+ data
247
+ end
248
+
249
+ # Update and existing metered usage belonging to this subscription and subscription item
250
+ # @param subscription_id [String] Unique identifier for Subscription object
251
+ # @param subscription_item_id [String] The unique identifier of the subscriptionItem
252
+ # @param usage_record_id [String] The unique identifier of the usage record
253
+ # @param update_usage_record [UpdateUsageRecord] Contains the quantity for the usage record to update
254
+ # @param [Hash] opts the optional parameters
255
+ # @return [Array<(UsageRecord, Integer, Hash)>] UsageRecord data, response status code and response headers
256
+ def put_usage_records_with_http_info(subscription_id, subscription_item_id, usage_record_id, update_usage_record, options = {})
257
+ opts = options.dup
258
+ if @api_client.config.debugging
259
+ @api_client.config.logger.debug 'Calling API: AppStoreApi.put_usage_records ...'
260
+ end
261
+ # verify the required parameter 'subscription_id' is set
262
+ if @api_client.config.client_side_validation && subscription_id.nil?
263
+ fail ArgumentError, "Missing the required parameter 'subscription_id' when calling AppStoreApi.put_usage_records"
264
+ end
265
+ # verify the required parameter 'subscription_item_id' is set
266
+ if @api_client.config.client_side_validation && subscription_item_id.nil?
267
+ fail ArgumentError, "Missing the required parameter 'subscription_item_id' when calling AppStoreApi.put_usage_records"
268
+ end
269
+ # verify the required parameter 'usage_record_id' is set
270
+ if @api_client.config.client_side_validation && usage_record_id.nil?
271
+ fail ArgumentError, "Missing the required parameter 'usage_record_id' when calling AppStoreApi.put_usage_records"
272
+ end
273
+ # verify the required parameter 'update_usage_record' is set
274
+ if @api_client.config.client_side_validation && update_usage_record.nil?
275
+ fail ArgumentError, "Missing the required parameter 'update_usage_record' when calling AppStoreApi.put_usage_records"
276
+ end
277
+ # resource path
278
+ local_var_path = '/subscriptions/{subscriptionId}/items/{subscriptionItemId}/usage-records/{usageRecordId}'.sub('{' + 'subscriptionId' + '}', subscription_id.to_s).sub('{' + 'subscriptionItemId' + '}', subscription_item_id.to_s).sub('{' + 'usageRecordId' + '}', usage_record_id.to_s)
279
+
280
+ # camelize keys of incoming `where` opts
281
+ opts[:'where'] = @api_client.parameterize_where(opts[:'where']) if !opts[:'where'].nil?
282
+
283
+ # query parameters
284
+ query_params = opts[:query_params] || {}
285
+
286
+ # XeroAPI's `IDs` convention openapi-generator does not snake_case properly.. manual over-riding `i_ds` malformations:
287
+ query_params[:'IDs'] = @api_client.build_collection_param(opts[:'ids'], :csv) if !opts[:'ids'].nil?
288
+ query_params[:'ContactIDs'] = @api_client.build_collection_param(opts[:'contact_ids'], :csv) if !opts[:'contact_ids'].nil?
289
+
290
+ # header parameters
291
+ header_params = opts[:header_params] || {}
292
+ # HTTP header 'Accept' (if needed)
293
+ header_params['Accept'] = @api_client.select_header_accept(['application/json'])
294
+ # HTTP header 'Content-Type'
295
+ header_params['Content-Type'] = @api_client.select_header_content_type(['application/json'])
296
+
297
+ # form parameters
298
+ form_params = opts[:form_params] || {}
299
+
300
+ # http body (model)
301
+ post_body = opts[:body] || @api_client.object_to_http_body(update_usage_record)
302
+
303
+ # return_type
304
+ return_type = opts[:return_type] || 'UsageRecord'
305
+
306
+ # auth_names
307
+ auth_names = opts[:auth_names] || ['OAuth2']
308
+
309
+ new_options = opts.merge(
310
+ :header_params => header_params,
311
+ :query_params => query_params,
312
+ :form_params => form_params,
313
+ :body => post_body,
314
+ :auth_names => auth_names,
315
+ :return_type => return_type
316
+ )
317
+
318
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, "AppStoreApi", new_options)
319
+ if @api_client.config.debugging
320
+ @api_client.config.logger.debug "API called: AppStoreApi#put_usage_records\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
321
+ end
322
+ return data, status_code, headers
323
+ end
86
324
  end
87
325
  end
@@ -46,7 +46,7 @@ module XeroRuby::Accounting
46
46
 
47
47
  attr_accessor :item
48
48
 
49
- # If you wish to omit either of the <Quantity> or <UnitAmount> you can provide a LineAmount and Xero will calculate the missing amount for you. The line amount reflects the discounted price if a DiscountRate has been used . i.e LineAmount = Quantity * Unit Amount * ((100 DiscountRate)/100)
49
+ # If you wish to omit either the Quantity or UnitAmount you can provide a LineAmount and Xero will calculate the missing amount for you. The line amount reflects the discounted price if either a DiscountRate or DiscountAmount has been used i.e. LineAmount = Quantity * Unit Amount * ((100 - DiscountRate)/100) or LineAmount = (Quantity * UnitAmount) - DiscountAmount
50
50
  attr_accessor :line_amount
51
51
 
52
52
  # Optional Tracking Category – see Tracking. Any LineItem can have a maximum of 2 <TrackingCategory> elements.
@@ -55,7 +55,7 @@ module XeroRuby::Accounting
55
55
  # Percentage discount being applied to a line item (only supported on ACCREC invoices – ACC PAY invoices and credit notes in Xero do not support discounts
56
56
  attr_accessor :discount_rate
57
57
 
58
- # Discount amount being applied to a line item. Only supported on ACCREC invoices - ACCPAY invoices and credit notes in Xero do not support discounts.
58
+ # Discount amount being applied to a line item. Only supported on ACCREC invoices and quotes. ACCPAY invoices and credit notes in Xero do not support discounts.
59
59
  attr_accessor :discount_amount
60
60
 
61
61
  # The Xero identifier for a Repeating Invoice
@@ -0,0 +1,243 @@
1
+ =begin
2
+ #Xero AppStore API
3
+
4
+ #These endpoints are for Xero Partners to interact with the App Store Billing platform
5
+
6
+ Contact: api@xero.com
7
+ Generated by: https://openapi-generator.tech
8
+ OpenAPI Generator version: 4.3.1
9
+
10
+ =end
11
+
12
+ require 'time'
13
+ require 'date'
14
+
15
+ module XeroRuby::AppStore
16
+ # Data transfer object for public create usage end point
17
+ require 'bigdecimal'
18
+
19
+ class CreateUsageRecord
20
+ # The initial quantity for the usage record. Must be a whole number that is greater than or equal to 0
21
+ attr_accessor :quantity
22
+
23
+ # DateTime in UTC of when the the product was consumed/used
24
+ attr_accessor :timestamp
25
+
26
+ # Attribute mapping from ruby-style variable name to JSON key.
27
+ def self.attribute_map
28
+ {
29
+ :'quantity' => :'quantity',
30
+ :'timestamp' => :'timestamp'
31
+ }
32
+ end
33
+
34
+ # Attribute type mapping.
35
+ def self.openapi_types
36
+ {
37
+ :'quantity' => :'Integer',
38
+ :'timestamp' => :'DateTime'
39
+ }
40
+ end
41
+
42
+ # Initializes the object
43
+ # @param [Hash] attributes Model attributes in the form of hash
44
+ def initialize(attributes = {})
45
+ if (!attributes.is_a?(Hash))
46
+ fail ArgumentError, "The input argument (attributes) must be a hash in `XeroRuby::AppStore::CreateUsageRecord` initialize method"
47
+ end
48
+
49
+ # check to see if the attribute exists and convert string to symbol for hash key
50
+ attributes = attributes.each_with_object({}) { |(k, v), h|
51
+ if (!self.class.attribute_map.key?(k.to_sym))
52
+ fail ArgumentError, "`#{k}` is not a valid attribute in `XeroRuby::AppStore::CreateUsageRecord`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
53
+ end
54
+ h[k.to_sym] = v
55
+ }
56
+
57
+ if attributes.key?(:'quantity')
58
+ self.quantity = attributes[:'quantity']
59
+ end
60
+
61
+ if attributes.key?(:'timestamp')
62
+ self.timestamp = attributes[:'timestamp']
63
+ end
64
+ end
65
+
66
+ # Show invalid properties with the reasons. Usually used together with valid?
67
+ # @return Array for valid properties with the reasons
68
+ def list_invalid_properties
69
+ invalid_properties = Array.new
70
+ if @quantity.nil?
71
+ invalid_properties.push('invalid value for "quantity", quantity cannot be nil.')
72
+ end
73
+
74
+ if @timestamp.nil?
75
+ invalid_properties.push('invalid value for "timestamp", timestamp cannot be nil.')
76
+ end
77
+
78
+ invalid_properties
79
+ end
80
+
81
+ # Check to see if the all the properties in the model are valid
82
+ # @return true if the model is valid
83
+ def valid?
84
+ return false if @quantity.nil?
85
+ return false if @timestamp.nil?
86
+ true
87
+ end
88
+
89
+ # Checks equality by comparing each attribute.
90
+ # @param [Object] Object to be compared
91
+ def ==(o)
92
+ return true if self.equal?(o)
93
+ self.class == o.class &&
94
+ quantity == o.quantity &&
95
+ timestamp == o.timestamp
96
+ end
97
+
98
+ # @see the `==` method
99
+ # @param [Object] Object to be compared
100
+ def eql?(o)
101
+ self == o
102
+ end
103
+
104
+ # Calculates hash code according to all attributes.
105
+ # @return [Integer] Hash code
106
+ def hash
107
+ [quantity, timestamp].hash
108
+ end
109
+
110
+ # Builds the object from hash
111
+ # @param [Hash] attributes Model attributes in the form of hash
112
+ # @return [Object] Returns the model itself
113
+ def self.build_from_hash(attributes)
114
+ new.build_from_hash(attributes)
115
+ end
116
+
117
+ # Builds the object from hash
118
+ # @param [Hash] attributes Model attributes in the form of hash
119
+ # @return [Object] Returns the model itself
120
+ def build_from_hash(attributes)
121
+ return nil unless attributes.is_a?(Hash)
122
+ self.class.openapi_types.each_pair do |key, type|
123
+ if type =~ /\AArray<(.*)>/i
124
+ # check to ensure the input is an array given that the attribute
125
+ # is documented as an array but the input is not
126
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
127
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
128
+ end
129
+ elsif !attributes[self.class.attribute_map[key]].nil?
130
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
131
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
132
+ end
133
+
134
+ self
135
+ end
136
+
137
+ # Deserializes the data based on type
138
+ # @param string type Data type
139
+ # @param string value Value to be deserialized
140
+ # @return [Object] Deserialized data
141
+ def _deserialize(type, value)
142
+ case type.to_sym
143
+ when :DateTime
144
+ DateTime.parse(parse_date(value))
145
+ when :Date
146
+ Date.parse(parse_date(value))
147
+ when :String
148
+ value.to_s
149
+ when :Integer
150
+ value.to_i
151
+ when :Float
152
+ value.to_f
153
+ when :BigDecimal
154
+ BigDecimal(value.to_s)
155
+ when :Boolean
156
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
157
+ true
158
+ else
159
+ false
160
+ end
161
+ when :Object
162
+ # generic object (usually a Hash), return directly
163
+ value
164
+ when /\AArray<(?<inner_type>.+)>\z/
165
+ inner_type = Regexp.last_match[:inner_type]
166
+ value.map { |v| _deserialize(inner_type, v) }
167
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
168
+ k_type = Regexp.last_match[:k_type]
169
+ v_type = Regexp.last_match[:v_type]
170
+ {}.tap do |hash|
171
+ value.each do |k, v|
172
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
173
+ end
174
+ end
175
+ else # model
176
+ XeroRuby::AppStore.const_get(type).build_from_hash(value)
177
+ end
178
+ end
179
+
180
+ # Returns the string representation of the object
181
+ # @return [String] String presentation of the object
182
+ def to_s
183
+ to_hash.to_s
184
+ end
185
+
186
+ # to_body is an alias to to_hash (backward compatibility)
187
+ # @return [Hash] Returns the object in the form of hash
188
+ def to_body
189
+ to_hash
190
+ end
191
+
192
+ # Returns the object in the form of hash
193
+ # @return [Hash] Returns the object in the form of hash
194
+ def to_hash(downcase: false)
195
+ hash = {}
196
+ self.class.attribute_map.each_pair do |attr, param|
197
+ value = self.send(attr)
198
+ next if value.nil?
199
+ key = downcase ? attr : param
200
+ hash[key] = _to_hash(value, downcase: downcase)
201
+ end
202
+ hash
203
+ end
204
+
205
+ # Returns the object in the form of hash with snake_case
206
+ def to_attributes
207
+ to_hash(downcase: true)
208
+ end
209
+
210
+ # Outputs non-array value in the form of hash
211
+ # For object, use to_hash. Otherwise, just return the value
212
+ # @param [Object] value Any valid value
213
+ # @return [Hash] Returns the value in the form of hash
214
+ def _to_hash(value, downcase: false)
215
+ if value.is_a?(Array)
216
+ value.map do |v|
217
+ v.to_hash(downcase: downcase)
218
+ end
219
+ elsif value.is_a?(Hash)
220
+ {}.tap do |hash|
221
+ value.map { |k, v| hash[k] = _to_hash(v, downcase: downcase) }
222
+ end
223
+ elsif value.respond_to? :to_hash
224
+ value.to_hash(downcase: downcase)
225
+ else
226
+ value
227
+ end
228
+ end
229
+
230
+ def parse_date(datestring)
231
+ if datestring.include?('Date')
232
+ date_pattern = /\/Date\((-?\d+)(\+\d+)?\)\//
233
+ original, date, timezone = *date_pattern.match(datestring)
234
+ date = (date.to_i / 1000)
235
+ Time.at(date).utc.strftime('%Y-%m-%dT%H:%M:%S%z').to_s
236
+ elsif /(\d\d\d\d)-(\d\d)/.match(datestring) # handles dates w/out Days: YYYY-MM*-DD
237
+ Time.parse(datestring + '-01').strftime('%Y-%m-%dT%H:%M:%S').to_s
238
+ else # handle date 'types' for small subset of payroll API's
239
+ Time.parse(datestring).strftime('%Y-%m-%dT%H:%M:%S').to_s
240
+ end
241
+ end
242
+ end
243
+ end