Skip to content

Commit 333589a

Browse files
authored
Merge pull request #31 from Sage/fix_v2.0.4-sage
Fix v2.0.4 sage
2 parents e35443b + a8aa20d commit 333589a

34 files changed

+782
-1405
lines changed

lib/zuora/api.rb

+21-61
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,21 @@ module Zuora
1111
# @return [Config]
1212
def self.configure(opts={})
1313
Api.instance.config = Config.new(opts)
14-
if Api.instance.config.sandbox
15-
Api.instance.sandbox!
16-
elsif Api.instance.config.services
17-
Api.instance.set_endpoint Api.instance.config.custom_url
18-
end
14+
HTTPI.logger = opts[:logger]
15+
HTTPI.log = opts[:logger] ? true : false
1916
end
2017

2118
class Api
22-
I18n.enforce_available_locales = false
23-
2419
# @return [Savon::Client]
25-
def client
26-
@client ||= make_client
27-
end
20+
attr_accessor :client
2821

2922
# @return [Zuora::Session]
3023
attr_accessor :session
3124

3225
# @return [Zuora::Config]
3326
attr_accessor :config
3427

35-
# Zuora::API Config options
36-
# @return [Hash]
37-
attr_accessor :options
38-
39-
WSDL = File.expand_path('../../../wsdl/zuora.a.78.0.wsdl', __FILE__)
4028
SOAP_VERSION = 2
41-
SANDBOX_ENDPOINT = 'https://apisandbox.zuora.com/apps/services/a/78.0'
42-
43-
def wsdl
44-
client.instance_variable_get(:@wsdl)
45-
end
4629

4730
def self.instance
4831
@instance ||= new
@@ -54,31 +37,15 @@ def authenticated?
5437
self.session.try(:active?)
5538
end
5639

57-
# Change client to use sandbox url
58-
def sandbox!
59-
@client = nil
60-
self.class.instance.client.globals[:endpoint] = SANDBOX_ENDPOINT
61-
end
62-
63-
#change the client to a specific endpoint
64-
def set_endpoint(endpoint)
65-
@client = nil
66-
self.class.instance.client.globals[:endpoint] = endpoint
67-
end
68-
69-
# Callback from Savon observer. Sets the @last_request
70-
# instance variable to the full request body.
71-
def notify(operation_name, builder, globals, locals)
72-
@last_request = builder.to_s
73-
return nil
74-
end
75-
7640
# The XML that was transmited in the last request
7741
# @return [String]
78-
attr_reader :last_request
42+
def last_request
43+
client.http.body
44+
end
7945

8046
# Generate an API request with the given block. The block yields an xml
8147
# builder instance which can be used to build out the request as needed.
48+
# You can also provide the xml_body which will be used instead of the block.
8249
# @param [Symbol] symbol of the WSDL operation to call
8350
# @param [String] string xml body pass to the operation
8451
# @yield [Builder] xml builder instance
@@ -91,6 +58,7 @@ def request(method, options={}, &block)
9158
yield xml
9259
options[:message] = xml.target!
9360
end
61+
options[:soap_header] = { 'env:SessionHeader' => { 'zns:Session' => self.session.try(:key) } }
9462
client.call(method, options)
9563
rescue Savon::SOAPFault, IOError => e
9664
raise Zuora::Fault.new(:message => e.message)
@@ -118,31 +86,23 @@ def download(export)
11886
# Upon failure a Zoura::Fault will be raised.
11987
# @raise [Zuora::Fault]
12088
def authenticate!
121-
response = client.call(:login) do
122-
message username: Zuora::Api.instance.config.username,
123-
password: Zuora::Api.instance.config.password
124-
end
89+
response = client.call(:login, message: { username: config.username, password: config.password })
90+
12591
self.session = Zuora::Session.generate(response.to_hash)
126-
client.globals.soap_header({'env:SessionHeader' => {'ins0:Session' => self.session.try(:key) }})
127-
rescue Savon::SOAPFault => e
92+
rescue Savon::SOAPFault, IOError => e
12893
raise Zuora::Fault.new(:message => e.message)
12994
end
13095

131-
private
132-
133-
def initialize
134-
@config = Config.new
135-
end
136-
137-
def make_client
138-
Savon.client(wsdl: fetch_wsdl, soap_version: SOAP_VERSION, log: config.log || true, ssl_verify_mode: :none)
139-
end
140-
141-
def fetch_wsdl
142-
config&.wsdl_path || WSDL
96+
def client
97+
return @client if @client
98+
99+
@client = Savon.client(
100+
wsdl: config&.wsdl_path ? config.wsdl_path : File.expand_path('../../../wsdl/zuora.a.38.0.wsdl', __FILE__),
101+
ssl_verify_mode: :none,
102+
soap_version: SOAP_VERSION,
103+
log: config&.log || true,
104+
filters: [:password]
105+
)
143106
end
144107
end
145-
146-
# Support request tracking via notify
147-
Savon.observers << Api.instance
148108
end

lib/zuora/attributes.rb

+15-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
module Zuora
22
module Attributes
3-
43
def self.included(base)
54
base.send(:include, ActiveModel::Naming)
65
base.send(:include, ActiveModel::Conversion)
@@ -40,17 +39,22 @@ def define_attributes(&block)
4039
# generate association overrides for complex object handling
4140
# and cache the objects so that they may be modified and updated
4241
class_variable_get(:@@complex_attributes).each do |var, scope|
42+
# set up the instance variable for the new assoc collection
43+
# for new records, but call the original one for existing
44+
# records and cache/return the result for subsequent calls.
4345
class_eval <<~EVAL
44-
prepend(Module.new do
45-
def #{scope}
46-
if new_record? || @#{scope}_cached
47-
@#{scope} ||= []
48-
else
49-
@#{scope}_cached = true
50-
@#{scope} = super
46+
prepend(
47+
Module.new do
48+
def #{scope}
49+
if new_record? || @#{scope}_cached
50+
@#{scope} ||= []
51+
else
52+
@#{scope}_cached = true
53+
@#{scope} = super
54+
end
5155
end
5256
end
53-
end)
57+
)
5458
EVAL
5559
end
5660
end
@@ -142,7 +146,7 @@ def remote_name
142146
def inherited(subclass)
143147
super
144148
xpath = "//xs:complexType[@name='#{subclass.remote_name}']//xs:sequence/xs:element"
145-
document = Zuora::Api.instance.wsdl.parser.instance_variable_get('@document')
149+
document = Zuora::Api.instance.client.wsdl.parser.instance_variable_get('@document')
146150
q = document.xpath(xpath, 's0' => 'http://schemas.xmlsoap.org/wsdl/', 'xs' => 'http://www.w3.org/2001/XMLSchema')
147151
wsdl_attrs = (q.map{|e| e.attributes['name'].to_s.underscore.to_sym }) << :id
148152
subclass.send(:class_variable_set, :@@wsdl_attributes, wsdl_attrs)
@@ -217,4 +221,4 @@ def remote_name
217221
self.class.name.base_name
218222
end
219223
end
220-
end
224+
end

lib/zuora/objects/account.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Account < Base
1313
validates_inclusion_of :payment_term, :in => ['Due Upon Receipt','Net 15','Net 30','Net 45','Net 90']
1414
validates_inclusion_of :batch, :in => (1..20).map{|n| "Batch#{n}" }
1515
validates_inclusion_of :bcd_setting_option, :in => ['AutoSet','ManualSet'], :allow_nil => true
16-
validates_inclusion_of :bill_cycle_day, :in => (1..31).to_a + (1..31).map(&:to_s)
16+
validates_inclusion_of :bill_cycle_day, :in => (1..30).to_a + (1..30).map(&:to_s)
1717
validates_inclusion_of :status, :in => ['Draft','Active','Canceled'], :allow_nil => true
1818

1919
define_attributes do
@@ -30,3 +30,4 @@ class Account < Base
3030
end
3131
end
3232
end
33+

lib/zuora/objects/amendment.rb

+20-19
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ module Zuora::Objects
22
class Amendment < Base
33
belongs_to :subscription
44

5-
validates_presence_of :subscription_id, :name
6-
validates_length_of :name, :maximum => 100
7-
validates_inclusion_of :auto_renew, :in => [true, false], :allow_nil => true
8-
validates_length_of :code, :maximum => 50, :allow_nil => true
9-
validates_date_of :contract_effective_date, :allow_nil => true
10-
validates_date_of :customer_acceptance_date, :allow_nil => true
11-
validates_date_of :effective_date, :allow_nil => true
12-
validates_date_of :service_activation_date, :if => Proc.new { |a| a.status == 'PendingAcceptance' }
13-
validates_length_of :description, :maximum => 500, :allow_nil => true
5+
validates_presence_of :subscription_id, :name
6+
validates_length_of :name, :maximum => 100
7+
validates_inclusion_of :auto_renew, :in => [true, false], :allow_nil => true
8+
validates_length_of :code, :maximum => 50, :allow_nil => true
9+
validates_datetime_of :contract_effective_date, :allow_nil => true
10+
validates_datetime_of :customer_acceptance_date, :allow_nil => true
11+
validates_datetime_of :effective_date, :allow_nil => true
12+
validates_datetime_of :service_activation_date, :if => Proc.new { |a| a.status == 'PendingAcceptance' }
13+
validates_length_of :description, :maximum => 500, :allow_nil => true
1414
validates_numericality_of :initial_term, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
1515
validates_numericality_of :renewal_term, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
16-
validates_date_of :term_start_date, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
17-
validates_presence_of :destination_account_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
18-
validates_presence_of :destination_invoice_owner_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
19-
validates_inclusion_of :status, :in => ["Completed", "Cancelled", "Draft", "Pending Acceptance", "Pending Activation"]
20-
validates_inclusion_of :term_type, :in => ['TERMED', 'EVERGREEN'], :allow_nil => true
21-
validates_inclusion_of :type, :in => ['Cancellation', 'NewProduct', 'OwnerTransfer', 'RemoveProduct', 'Renewal', 'UpdateProduct', 'TermsAndConditions']
22-
validates_presence_of :rate_plan_data, :if => Proc.new { |a| ['NewProduct', 'RemoveProduct', 'UpdateProduct'].include?(a.type) }, :only => :apply_percentage_discount
16+
validates_date_of :term_start_date, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
17+
validates_presence_of :destination_account_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
18+
validates_presence_of :destination_invoice_owner_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
19+
validates_inclusion_of :status, :in => ["Completed", "Cancelled", "Draft", "Pending Acceptance", "Pending Activation"]
20+
validates_inclusion_of :term_type, :in => ['TERMED', 'EVERGREEN'], :allow_nil => true
21+
validates_inclusion_of :type, :in => ['Cancellation', 'NewProduct', 'OwnerTransfer', 'RemoveProduct', 'Renewal', 'UpdateProduct', 'TermsAndConditions']
22+
validates_presence_of :rate_plan_data, :if => Proc.new { |a| ['NewProduct', 'RemoveProduct', 'UpdateProduct'].include?(a.type) }, :only => :apply_percentage_discount
2323

2424
attr_accessor :amendment_ids
2525
attr_accessor :invoice_id
@@ -32,10 +32,12 @@ class Amendment < Base
3232

3333
def apply_percentage_discount
3434
self.status = 'Completed'
35-
result = self.connector.amend
35+
result = self.connector.amend({ 'process_payments' => false })
3636
apply_percentage_discount_response(result.to_hash, :amend_response)
3737
end
3838

39+
private
40+
3941
def apply_percentage_discount_response(response_hash, type)
4042
result = response_hash[type][:results]
4143
if result[:success]
@@ -46,8 +48,7 @@ def apply_percentage_discount_response(response_hash, type)
4648
clear_changes_information
4749
return true
4850
else
49-
self.errors.add(:base, result[:errors][:message])
50-
return false
51+
raise StandardError.new(result[:errors][:message])
5152
end
5253
end
5354
end

lib/zuora/objects/base.rb

+3-23
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@ class Base
99
# generate a new instance of a Zuora object
1010
def initialize(attrs={}, &block)
1111
apply_default_attributes
12-
self.attributes = attrs
13-
yield self if block_given?
14-
end
15-
16-
def attributes=(attrs={})
1712
attrs.each do |name, value|
1813
self.send("#{name.to_s.underscore}=", value)
1914
end
15+
yield self if block_given?
2016
end
2117

2218
# given a soap response hash, initialize a record
@@ -55,7 +51,7 @@ def self.unselectable_attributes
5551
end
5652

5753
def self.namespace(uri)
58-
Zuora::Api.instance.client.operation(:query).build.send(:namespace_by_uri, uri)
54+
connector.current_client.client.operation(:query).build.send(:namespace_by_uri, uri)
5955
end
6056

6157
def self.zns
@@ -80,24 +76,14 @@ def self.select(select)
8076
self
8177
end
8278

83-
# retrieve all of the records
84-
def self.all
85-
keys = (attributes - unselectable_attributes).map(&:to_s).map(&:zuora_camelize)
86-
sql = "select #{keys.join(', ')} from #{remote_name}"
87-
88-
result = self.connector.query(sql)
89-
90-
generate(result.to_hash, :query_response)
91-
end
92-
9379
# locate objects using a custom where clause, currently arel
9480
# is not supported as it requires an actual db connection to
9581
# generate the sql queries. This may be overcome in the future.
9682
def self.where(where)
9783
keys = self.select_attributes
9884
if where.is_a?(Hash)
9985
# FIXME: improper inject usage.
100-
where = where.inject([]){|t,v| t << "#{v[0].to_s.zuora_camelize} = '#{v[1]}'"}.sort.join(' and ')
86+
where = where.inject([]){|t,v| t << "#{v[0].to_s.camelcase} = '#{v[1]}'"}.sort.join(' and ')
10187
end
10288
sql = "select #{keys.join(', ')} from #{remote_name} where #{where}"
10389

@@ -108,11 +94,6 @@ def self.where(where)
10894
generate(result.to_hash, :query_response)
10995
end
11096

111-
def self.query(query_string)
112-
result = self.connector.query(query_string)
113-
generate(result.to_hash, :query_response)
114-
end
115-
11697
# has this record not been saved?
11798
def new_record?
11899
id.nil?
@@ -205,4 +186,3 @@ def self.select_attributes
205186

206187
end
207188
end
208-
+18-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
module Zuora::Objects
2-
class CreditBalanceAdjustment < Base
3-
belongs_to :account
4-
belongs_to :source_transaction
1+
#module Zuora::Objects
2+
#class CreditBalanceAdjustment < Base
3+
#belongs_to :account
4+
#belongs_to :source_transaction
55

6-
validates_length_of :accounting_code, :maximum => 100, :allow_nil => true
7-
validates_numericality_of :amount
8-
validates_length_of :comment, :maximum => 255, :allow_nil => true
9-
validates_length_of :reference_id, :maximum => 60, :allow_nil => true
10-
validates_presence_of :source_transaction_id, :if => Proc.new { |c| c.source_transaction_type == 'Adjustment' }
11-
validates_inclusion_of :source_transaction_type, :in => %w(Invoice Payment Refund Adjustment), :unless => :source_transaction
12-
validates_length_of :source_transaction_number, :maximum => 50, :if => Proc.new { |c| c.source_transaction_type == 'Adjustment' && !c.source_transaction }
13-
validates_inclusion_of :transferred_to_accounting, :in => %w(Processing Yes Error Ignore), :allow_nil => true
14-
validates_inclusion_of :type, :in => %w(Increase Decrease)
6+
#validates_length_of :accounting_code, :maximum => 100, :allow_nil => true
7+
#validates_numericality_of :amount
8+
#validates_length_of :comment, :maximum => 255, :allow_nil => true
9+
#validates_length_of :reference_id, :maximum => 60, :allow_nil => true
10+
#validates_presence_of :source_transaction_id, :if => Proc.new { |c| c.source_transaction_type == 'Adjustment' }
11+
#validates_inclusion_of :source_transaction_type, :in => %w(Invoice Payment Refund Adjustment), :unless => :source_transaction
12+
#validates_length_of :source_transaction_number, :maximum => 50, :if => Proc.new { |c| c.source_transaction_type == 'Adjustment' && !c.source_transaction }
13+
#validates_inclusion_of :transferred_to_accounting, :in => %w(Processing Yes Error Ignore), :allow_nil => true
14+
#validates_inclusion_of :type, :in => %w(Increase Decrease)
1515

16-
define_attributes do
17-
read_only :created_by_id, :created_date, :updated_by_id, :updated_date
18-
end
19-
end
20-
end
16+
#define_attributes do
17+
#read_only :created_by_id, :created_date, :updated_by_id, :updated_date
18+
#end
19+
#end
20+
#end

lib/zuora/objects/invoice.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class Invoice < Base
1515
validates_numericality_of :amount
1616
validates_numericality_of :balance, :allow_nil => true
1717
validates_length_of :comments, :maximum => 255
18-
validates_date_of :due_date
19-
validates_date_of :invoice_date
18+
validates_datetime_of :due_date
19+
validates_datetime_of :invoice_date
2020
validates_inclusion_of :includes_one_time, :in => [true, false]
2121
validates_inclusion_of :includes_recurring, :in => [true, false]
2222
validates_inclusion_of :includes_usage, :in => [true, false]
@@ -26,7 +26,7 @@ class Invoice < Base
2626
validates_datetime_of :posted_date, :allow_nil => true
2727
validates_numericality_of :refund_amount, :allow_nil => true
2828
validates_inclusion_of :status, :in => %w(Canceled Draft Error Posted), :allow_nil => true
29-
validates_date_of :target_date
29+
validates_datetime_of :target_date
3030
validates_inclusion_of :transferred_to_accounting, :in => %w(Processing Yes Error Ignore), :allow_nil => true
3131
validates_datetime_of :updated_date
3232

0 commit comments

Comments
 (0)