active_zuora 1.3.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
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