active_zuora 1.3.0 → 2.6.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. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.octopolo.yml +4 -0
  4. data/.soyuz.yml +13 -0
  5. data/.travis.yml +7 -0
  6. data/CHANGELOG.markdown +41 -0
  7. data/Gemfile +4 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +191 -0
  10. data/Rakefile +9 -53
  11. data/TODO.md +2 -0
  12. data/active_zuora.gemspec +25 -59
  13. data/lib/active_zuora.rb +44 -12
  14. data/lib/active_zuora/amend.rb +43 -0
  15. data/lib/active_zuora/base.rb +84 -0
  16. data/lib/active_zuora/batch_subscribe.rb +53 -0
  17. data/lib/active_zuora/belongs_to_associations.rb +56 -0
  18. data/lib/active_zuora/billing_preview.rb +49 -0
  19. data/lib/active_zuora/collection_proxy.rb +38 -0
  20. data/lib/active_zuora/connection.rb +47 -0
  21. data/lib/active_zuora/fields.rb +129 -0
  22. data/lib/active_zuora/fields/array_field_decorator.rb +28 -0
  23. data/lib/active_zuora/fields/boolean_field.rb +12 -0
  24. data/lib/active_zuora/fields/date_field.rb +18 -0
  25. data/lib/active_zuora/fields/date_time_field.rb +19 -0
  26. data/lib/active_zuora/fields/decimal_field.rb +12 -0
  27. data/lib/active_zuora/fields/field.rb +76 -0
  28. data/lib/active_zuora/fields/integer_field.rb +11 -0
  29. data/lib/active_zuora/fields/object_field.rb +31 -0
  30. data/lib/active_zuora/fields/string_field.rb +11 -0
  31. data/lib/active_zuora/generate.rb +43 -0
  32. data/lib/active_zuora/generator.rb +244 -0
  33. data/lib/active_zuora/has_many_associations.rb +37 -0
  34. data/lib/active_zuora/has_many_proxy.rb +50 -0
  35. data/lib/active_zuora/lazy_attr.rb +52 -0
  36. data/lib/active_zuora/persistence.rb +172 -0
  37. data/lib/active_zuora/relation.rb +260 -0
  38. data/lib/active_zuora/scoping.rb +50 -0
  39. data/lib/active_zuora/subscribe.rb +42 -0
  40. data/lib/active_zuora/version.rb +3 -0
  41. data/lib/active_zuora/z_object.rb +21 -0
  42. data/spec/account_integration_spec.rb +41 -0
  43. data/spec/base_spec.rb +39 -0
  44. data/spec/belongs_to_associations_spec.rb +35 -0
  45. data/spec/collection_proxy_spec.rb +28 -0
  46. data/spec/connection_spec.rb +66 -0
  47. data/spec/fields/date_field_spec.rb +35 -0
  48. data/spec/has_many_integration_spec.rb +53 -0
  49. data/spec/lazy_attr_spec.rb +22 -0
  50. data/spec/spec_helper.rb +34 -0
  51. data/spec/subscribe_integration_spec.rb +344 -0
  52. data/spec/zobject_integration_spec.rb +104 -0
  53. data/wsdl/zuora.wsdl +1548 -0
  54. metadata +141 -53
  55. data/LICENSE +0 -202
  56. data/README.rdoc +0 -15
  57. data/VERSION +0 -1
  58. data/custom_fields.yml +0 -17
  59. data/lib/zuora/ZUORA.rb +0 -1398
  60. data/lib/zuora/ZUORADriver.rb +0 -128
  61. data/lib/zuora/ZUORAMappingRegistry.rb +0 -1488
  62. data/lib/zuora/ZuoraServiceClient.rb +0 -124
  63. data/lib/zuora/account.rb +0 -4
  64. data/lib/zuora/api.rb +0 -18
  65. data/lib/zuora/contact.rb +0 -4
  66. data/lib/zuora/rate_plan.rb +0 -4
  67. data/lib/zuora/rate_plan_data.rb +0 -4
  68. data/lib/zuora/subscribe_options.rb +0 -4
  69. data/lib/zuora/subscribe_request.rb +0 -4
  70. data/lib/zuora/subscribe_with_existing_account_request.rb +0 -4
  71. data/lib/zuora/subscription.rb +0 -4
  72. data/lib/zuora/subscription_data.rb +0 -4
  73. data/lib/zuora/zobject.rb +0 -52
  74. data/lib/zuora_client.rb +0 -181
  75. data/lib/zuora_interface.rb +0 -199
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'active_zuora'
4
+
5
+ I18n.enforce_available_locales = true
6
+
7
+ ActiveZuora.configure(
8
+ :log => !!ENV['DEBUG'],
9
+ :pretty_print_xml => !!ENV['DEBUG'],
10
+ :username => ENV['ZUORA_USER'],
11
+ :password => ENV['ZUORA_PASS']
12
+ )
13
+
14
+ module Z; end
15
+ ActiveZuora.generate_classes :inside => Z
16
+
17
+ def integration_test
18
+ # Block helper. Integration tests should be wrapped in this block.
19
+ if ENV['ZUORA_USER'] && ENV['ZUORA_PASS']
20
+ yield
21
+ else
22
+ $stderr.puts "Integration tests skipped because ZUORA_USER or ZUORA_PASS are not set."
23
+ end
24
+ end
25
+
26
+ def now(_message)
27
+ yield
28
+ end
29
+
30
+ module Tenant
31
+ def self.currency
32
+ ENV['ZUORA_CURRENCY'] || 'USD'
33
+ end
34
+ end
@@ -0,0 +1,344 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Subscribe" do
4
+ integration_test do
5
+ before(:all) do
6
+ # Setup product.
7
+ @product = Z::Product.where(:name => "Awesome Product").first ||
8
+ Z::Product.create!(
9
+ :name => "Awesome Product",
10
+ :effective_start_date => Date.today,
11
+ :effective_end_date => Date.today + 10.years
12
+ )
13
+ @product_rate_plan = @product.product_rate_plans.first ||
14
+ Z::ProductRatePlan.create!(
15
+ :product => @product,
16
+ :name => "Awesome Plan"
17
+ )
18
+ @product_rate_plan_charge = @product_rate_plan.product_rate_plan_charges.first ||
19
+ Z::ProductRatePlanCharge.create!(
20
+ :product_rate_plan => @product_rate_plan,
21
+ :name => "Monthly Service",
22
+ :charge_model => "Flat Fee Pricing",
23
+ :charge_type => "Recurring",
24
+ :billing_period => "Month",
25
+ :trigger_event => "ContractEffective",
26
+ :product_rate_plan_charge_tier_data => {
27
+ :product_rate_plan_charge_tier => {
28
+ :active => true,
29
+ :currency => Tenant.currency,
30
+ :tier => 1,
31
+ :price => 50.00,
32
+ :starting_unit => 1,
33
+ :ending_unit => 1000
34
+ }
35
+ }
36
+ )
37
+ end
38
+
39
+ after(:all) { @product.try(:delete) }
40
+
41
+ it "Can successfully subscribe and amend using a new account" do
42
+
43
+ subscribe_request = Z::SubscribeRequest.new(
44
+ :account => {
45
+ :name => "Joe Customer",
46
+ :currency => Tenant.currency,
47
+ :bill_cycle_day => 1,
48
+ :payment_term => "Due Upon Receipt",
49
+ :batch => "Batch1"
50
+ },
51
+ :payment_method => {
52
+ :type => "CreditCard",
53
+ :credit_card_holder_name => "Robert Paulson",
54
+ :credit_card_type => "MasterCard",
55
+ :credit_card_number => "5424000000000015",
56
+ :credit_card_expiration_month => 1,
57
+ :credit_card_expiration_year => (Date.today.year + 1)
58
+ },
59
+ :bill_to_contact => {
60
+ :first_name => "Conny",
61
+ :last_name => "Client",
62
+ :country => "AU",
63
+ :work_email => "conny.client@example.com"
64
+ },
65
+ :subscription_data => {
66
+ :subscription => {
67
+ :contract_effective_date => Date.today,
68
+ :service_activation_date => Date.today,
69
+ :initial_term => 12,
70
+ :renewal_term => 12
71
+ },
72
+ :rate_plan_data => {
73
+ :rate_plan => {
74
+ :product_rate_plan_id => @product_rate_plan.id,
75
+ },
76
+ :rate_plan_charge_data => {
77
+ :rate_plan_charge => {
78
+ :product_rate_plan_charge_id => @product_rate_plan_charge.id,
79
+ :price => 45.00
80
+ }
81
+ }
82
+ }
83
+ }
84
+ )
85
+
86
+ subscribe_request.subscribe!
87
+ account = subscribe_request.account
88
+
89
+ expect(account.new_record?).to be_falsey
90
+ expect(account.changed?).to be_falsey
91
+ expect(subscribe_request.subscription_data.subscription.new_record?).to be_falsey
92
+ expect(subscribe_request.subscription_data.subscription.rate_plans.first.
93
+ rate_plan_charges.first.
94
+ product_rate_plan_charge).to eq(@product_rate_plan_charge)
95
+ expect(subscribe_request.result).to be_present
96
+
97
+ # Now amend the subscription
98
+ subscription = subscribe_request.subscription_data.subscription.reload
99
+ amend_request = Z::AmendRequest.new(
100
+ :amendments => {
101
+ :name => "Remove Awesome Plan",
102
+ :contract_effective_date => Date.today,
103
+ :service_activation_date => Date.today,
104
+ :subscription_id => subscription.id,
105
+ :type => "RemoveProduct",
106
+ :rate_plan_data => {
107
+ :rate_plan => {
108
+ :amendment_subscription_rate_plan_id => subscription.rate_plans.first.id
109
+ }
110
+ }
111
+ },
112
+ :amend_options => {
113
+ :generate_invoice => false,
114
+ :process_payments => false
115
+ }
116
+ )
117
+ amend_request.amend!
118
+ expect(amend_request.amendments.first.new_record?).to be_falsey
119
+ expect(amend_request.result).to be_present
120
+
121
+ account.delete
122
+ end
123
+
124
+ it "Can successfully subscribe and generate a bill preview and an invoice" do
125
+
126
+ subscribe_request = Z::SubscribeRequest.new(
127
+ :account => {
128
+ :name => "Joe Customer",
129
+ :currency => Tenant.currency,
130
+ :bill_cycle_day => 1,
131
+ :payment_term => "Due Upon Receipt",
132
+ :batch => "Batch1"
133
+ },
134
+ :payment_method => {
135
+ :type => "CreditCard",
136
+ :credit_card_holder_name => "Robert Paulson",
137
+ :credit_card_type => "MasterCard",
138
+ :credit_card_number => "4111111111111111",
139
+ :credit_card_expiration_month => 1,
140
+ :credit_card_expiration_year => (Date.today.year + 1)
141
+ },
142
+ :bill_to_contact => {
143
+ :first_name => "Conny",
144
+ :last_name => "Client",
145
+ :work_email => "conny.client@example.com",
146
+ :country => "AU"
147
+ },
148
+ :subscription_data => {
149
+ :subscription => {
150
+ :contract_effective_date => Date.today,
151
+ :service_activation_date => Date.today,
152
+ :initial_term => 12,
153
+ :renewal_term => 12,
154
+ :term_type => 'TERMED'
155
+ },
156
+ :rate_plan_data => {
157
+ :rate_plan => {
158
+ :product_rate_plan_id => @product_rate_plan.id,
159
+ },
160
+ :rate_plan_charge_data => {
161
+ :rate_plan_charge => {
162
+ :product_rate_plan_charge_id => @product_rate_plan_charge.id,
163
+ :price => 45.00
164
+ }
165
+ }
166
+ }
167
+ }
168
+ )
169
+
170
+ subscribe_request.subscribe!
171
+ account = subscribe_request.account
172
+
173
+ expect(account.new_record?).to be_falsey
174
+ expect(account.changed?).to be_falsey
175
+ expect(subscribe_request.subscription_data.subscription.new_record?).to be_falsey
176
+ expect(subscribe_request.subscription_data.subscription.rate_plans.first.
177
+ rate_plan_charges.first.
178
+ product_rate_plan_charge).to eq(@product_rate_plan_charge)
179
+ expect(subscribe_request.result).to be_present
180
+
181
+ # Now renew the subscription
182
+ subscription = subscribe_request.subscription_data.subscription.reload
183
+
184
+ amend_request = Z::AmendRequest.new(
185
+ :amendments => {
186
+ :name => "Renew",
187
+ :contract_effective_date => Date.today + 12.months,
188
+ :effective_date => Date.today,
189
+ :subscription_id => subscription.id,
190
+ :type => "Renewal",
191
+ :auto_renew => false,
192
+ :renewal_term => 12
193
+ },
194
+ :amend_options => {
195
+ :generate_invoice => false,
196
+ :process_payments => false
197
+ }
198
+ )
199
+ amend_request.amend!
200
+ expect(amend_request.amendments.first.new_record?).to be_falsey
201
+ expect(amend_request.result).to be_present
202
+
203
+ billing_preview_request = Z::BillingPreviewRequest.new(
204
+ account_id: subscribe_request.account.id,
205
+ target_date: Date.today + 2.months
206
+ )
207
+
208
+ billing_preview_result = billing_preview_request.billing_preview!
209
+ expect(billing_preview_result).to be_present
210
+ expect(billing_preview_result.invoice_item).to be_present
211
+
212
+ invoice = Z::Invoice.new(
213
+ account_id: subscribe_request.account.id,
214
+ invoice_date: Date.today,
215
+ target_date: Date.today + 12.months,
216
+ includes_one_time: false,
217
+ includes_recurring: true,
218
+ includes_usage: false
219
+ )
220
+ invoice.generate!
221
+ expect(invoice.id).to be_present
222
+ expect(invoice.account_id).to eq(subscribe_request.account.id)
223
+ expect(invoice.body).to be_present
224
+
225
+ account.delete
226
+ end
227
+
228
+ it "Can successfully batch subscribe from a collection proxy of subscribe requests and generate an invoice for the first subscription" do
229
+ subscribe_request_1 = Z::SubscribeRequest.new(
230
+ :account => {
231
+ :name => "Joe Customer",
232
+ :currency => Tenant.currency,
233
+ :bill_cycle_day => 1,
234
+ :payment_term => "Due Upon Receipt",
235
+ :batch => "Batch1"
236
+ },
237
+ :payment_method => {
238
+ :type => "CreditCard",
239
+ :credit_card_holder_name => "Robert Paulson",
240
+ :credit_card_type => "MasterCard",
241
+ :credit_card_number => "4111111111111111",
242
+ :credit_card_expiration_month => 1,
243
+ :credit_card_expiration_year => (Date.today.year + 1)
244
+ },
245
+ :bill_to_contact => {
246
+ :first_name => "Conny",
247
+ :last_name => "Client",
248
+ :work_email => "conny.client@example.com",
249
+ :country => "AU"
250
+ },
251
+ :subscription_data => {
252
+ :subscription => {
253
+ :contract_effective_date => Date.today,
254
+ :service_activation_date => Date.today,
255
+ :initial_term => 12,
256
+ :renewal_term => 12,
257
+ :term_type => 'TERMED'
258
+ },
259
+ :rate_plan_data => {
260
+ :rate_plan => {
261
+ :product_rate_plan_id => @product_rate_plan.id,
262
+ },
263
+ :rate_plan_charge_data => {
264
+ :rate_plan_charge => {
265
+ :product_rate_plan_charge_id => @product_rate_plan_charge.id,
266
+ :price => 45.00
267
+ }
268
+ }
269
+ }
270
+ }
271
+ )
272
+
273
+ subscribe_request_2 = Z::SubscribeRequest.new(
274
+ :account => {
275
+ :name => "Joe Customer",
276
+ :currency => Tenant.currency,
277
+ :bill_cycle_day => 1,
278
+ :payment_term => "Due Upon Receipt",
279
+ :batch => "Batch1"
280
+ },
281
+ :payment_method => {
282
+ :type => "CreditCard",
283
+ :credit_card_holder_name => "Robert Paulson",
284
+ :credit_card_type => "MasterCard",
285
+ :credit_card_number => "4111111111111111",
286
+ :credit_card_expiration_month => 1,
287
+ :credit_card_expiration_year => (Date.today.year + 1)
288
+ },
289
+ :bill_to_contact => {
290
+ :first_name => "Conny",
291
+ :last_name => "Client",
292
+ :work_email => "conny.client@example.com",
293
+ :country => "AU"
294
+ },
295
+ :subscription_data => {
296
+ :subscription => {
297
+ :contract_effective_date => Date.today,
298
+ :service_activation_date => Date.today,
299
+ :initial_term => 12,
300
+ :renewal_term => 12,
301
+ :term_type => 'TERMED'
302
+ },
303
+ :rate_plan_data => {
304
+ :rate_plan => {
305
+ :product_rate_plan_id => @product_rate_plan.id,
306
+ },
307
+ :rate_plan_charge_data => {
308
+ :rate_plan_charge => {
309
+ :product_rate_plan_charge_id => @product_rate_plan_charge.id,
310
+ :price => 45.00
311
+ }
312
+ }
313
+ }
314
+ }
315
+ )
316
+
317
+ collection = Z::CollectionProxy.new([subscribe_request_1,subscribe_request_2])
318
+ collection.batch_subscribe!
319
+
320
+ account_1 = subscribe_request_1.account
321
+ account_2 = subscribe_request_2.account
322
+
323
+ #subscribe reqeust 1
324
+ expect(account_1.new_record?).to be_falsey
325
+ expect(account_1.changed?).to be_falsey
326
+ expect(subscribe_request_1.subscription_data.subscription.new_record?).to be_falsey
327
+ expect(subscribe_request_1.subscription_data.subscription.rate_plans.first.
328
+ rate_plan_charges.first.
329
+ product_rate_plan_charge).to eq(@product_rate_plan_charge)
330
+ expect(subscribe_request_1.result).to be_present
331
+
332
+ #subscribe reqeust 2
333
+ expect(account_2.new_record?).to be_falsey
334
+ expect(account_2.changed?).to be_falsey
335
+ expect(subscribe_request_2.subscription_data.subscription.new_record?).to be_falsey
336
+ expect(subscribe_request_2.subscription_data.subscription.rate_plans.first.
337
+ rate_plan_charges.first.
338
+ product_rate_plan_charge).to eq(@product_rate_plan_charge)
339
+ expect(subscribe_request_2.result).to be_present
340
+
341
+ [account_1, account_2].each(&:delete)
342
+ end
343
+ end
344
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ZObject" do
4
+
5
+ integration_test do
6
+
7
+ after do
8
+ # Delete the account to cleanup in case a test failed.
9
+ @account.delete if @account
10
+ @child.delete if @child
11
+ end
12
+
13
+ it "can be created, queried, updated, and destroyed" do
14
+
15
+ # Test failed creation.
16
+ @account = Z::Account.create
17
+ expect(@account.new_record?).to be_truthy
18
+ expect(@account.errors).to be_present
19
+
20
+ # Test creation.
21
+ @account = Z::Account.new(
22
+ :name => "ZObject Integration Test Account",
23
+ :currency => Tenant.currency,
24
+ :status => "Draft",
25
+ :bill_cycle_day => 1)
26
+ expect(@account.changes).to be_present
27
+ expect(@account.save).to be_truthy
28
+ expect(@account.new_record?).to be_falsey
29
+ expect(@account.errors).to be_blank
30
+ expect(@account.changes).to be_blank
31
+
32
+ # Test update.
33
+ @account.name = "ZObject Integration Test Account 2"
34
+ expect(@account.changes).to be_present
35
+ expect(@account.save).to be_truthy
36
+ expect(@account.changes).to be_blank
37
+
38
+ # Test querying.
39
+ expect(Z::Account.where(:name => "Some Random Name").all.to_a).to_not include(@account)
40
+ expect(Z::Account.where(:name => "Some Random Name").or(:name => @account.name).all.to_a).to include(@account)
41
+ expect(Z::Account.where(:created_date => { ">=" => Date.yesterday }).all.to_a).to include(@account)
42
+ expect(Z::Account.where(:created_date => { ">" => Time.now }).or(:name => @account.name).all.to_a).to include(@account)
43
+ Z::Account.where(:created_date => { ">=" => Date.today }).find_each do |account|
44
+ expect(account).to be_present
45
+ end
46
+
47
+ # Test ordering
48
+ unordered = Z::Account.where(:created_date => { ">=" => Date.today })
49
+ ordered = unordered.order(:name, :desc)
50
+ expect(unordered.order_attribute).to eq(:created_date)
51
+ expect(unordered.order_direction).to eq(:asc)
52
+ expect(ordered.order_attribute).to eq(:name)
53
+ expect(ordered.order_direction).to eq(:desc)
54
+
55
+ # Test scopes and chaining.
56
+ Z::Account.instance_eval do
57
+ scope :draft, :status => "Draft"
58
+ scope :active, where(:status => "Active")
59
+ scope :since, lambda { |datetime| where(:created_date => { ">=" => datetime }) }
60
+ end
61
+ expect(Z::Account.select(:id).draft.to_zql).to eq("select Id from Account where Status = 'Draft'")
62
+ expect(Z::Account.select(:id).active.since(Date.new 2012).to_zql).to eq("select Id from Account where Status = 'Active' and CreatedDate >= '2012-01-01T00:00:00+08:00'")
63
+
64
+ # Update all.
65
+ expect(Z::Account.where(:name => @account.name).update_all(:name => "ZObject Integration Test Account 3")).to eq(1)
66
+ expect(@account.reload.name).to eq("ZObject Integration Test Account 3")
67
+ # Block-style update_all
68
+ expect(Z::Account.where(:name => @account.name).update_all { |account| account.name += "4" }).to eq(1)
69
+ expect(@account.reload.name).to eq("ZObject Integration Test Account 34")
70
+ # No changes, so no records were updated.
71
+ expect(Z::Account.where(:name => @account.name).update_all(:name => "ZObject Integration Test Account 34")).to eq(0)
72
+
73
+ # Associations
74
+ @child = Z::Account.create!(
75
+ :parent_id => @account.id,
76
+ :name => "ZObject Integration Test Child Account",
77
+ :currency => Tenant.currency,
78
+ :status => "Draft",
79
+ :bill_cycle_day => 1)
80
+ expect(@account.children.to_a).to include(@child)
81
+ expect(@child.parent).to eq(@account)
82
+ # Make sure that the has_many pre-loads the inverse relationship.
83
+ @account.children.each { |child| expect(child.parent_loaded?).to be_truthy }
84
+
85
+ # Testing batch creates
86
+ batch_accounts = []
87
+ batch_number = 55
88
+ (1..batch_number).each do |i|
89
+ batch_accounts << Z::Account.new(
90
+ :name => @account.name,
91
+ :currency => Tenant.currency,
92
+ :status => "Draft",
93
+ :bill_cycle_day => 1)
94
+ end
95
+ expect(Z::Account.save(batch_accounts)).to eq(batch_number)
96
+
97
+ # Delete all
98
+ expect(Z::Account.where(:name => @account.name).delete_all).to be >= 1
99
+ @account = nil
100
+
101
+ end
102
+
103
+ end
104
+ end