Skip to content

Commit

Permalink
Merge pull request #31 from Sage/fix_v2.0.4-sage
Browse files Browse the repository at this point in the history
Fix v2.0.4 sage
  • Loading branch information
banjoko01 authored Jul 29, 2024
2 parents e35443b + a8aa20d commit 333589a
Show file tree
Hide file tree
Showing 34 changed files with 782 additions and 1,405 deletions.
82 changes: 21 additions & 61 deletions lib/zuora/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,21 @@ module Zuora
# @return [Config]
def self.configure(opts={})
Api.instance.config = Config.new(opts)
if Api.instance.config.sandbox
Api.instance.sandbox!
elsif Api.instance.config.services
Api.instance.set_endpoint Api.instance.config.custom_url
end
HTTPI.logger = opts[:logger]
HTTPI.log = opts[:logger] ? true : false
end

class Api
I18n.enforce_available_locales = false

# @return [Savon::Client]
def client
@client ||= make_client
end
attr_accessor :client

# @return [Zuora::Session]
attr_accessor :session

# @return [Zuora::Config]
attr_accessor :config

# Zuora::API Config options
# @return [Hash]
attr_accessor :options

WSDL = File.expand_path('../../../wsdl/zuora.a.78.0.wsdl', __FILE__)
SOAP_VERSION = 2
SANDBOX_ENDPOINT = 'https://apisandbox.zuora.com/apps/services/a/78.0'

def wsdl
client.instance_variable_get(:@wsdl)
end

def self.instance
@instance ||= new
Expand All @@ -54,31 +37,15 @@ def authenticated?
self.session.try(:active?)
end

# Change client to use sandbox url
def sandbox!
@client = nil
self.class.instance.client.globals[:endpoint] = SANDBOX_ENDPOINT
end

#change the client to a specific endpoint
def set_endpoint(endpoint)
@client = nil
self.class.instance.client.globals[:endpoint] = endpoint
end

# Callback from Savon observer. Sets the @last_request
# instance variable to the full request body.
def notify(operation_name, builder, globals, locals)
@last_request = builder.to_s
return nil
end

# The XML that was transmited in the last request
# @return [String]
attr_reader :last_request
def last_request
client.http.body
end

# Generate an API request with the given block. The block yields an xml
# builder instance which can be used to build out the request as needed.
# You can also provide the xml_body which will be used instead of the block.
# @param [Symbol] symbol of the WSDL operation to call
# @param [String] string xml body pass to the operation
# @yield [Builder] xml builder instance
Expand All @@ -91,6 +58,7 @@ def request(method, options={}, &block)
yield xml
options[:message] = xml.target!
end
options[:soap_header] = { 'env:SessionHeader' => { 'zns:Session' => self.session.try(:key) } }
client.call(method, options)
rescue Savon::SOAPFault, IOError => e
raise Zuora::Fault.new(:message => e.message)
Expand Down Expand Up @@ -118,31 +86,23 @@ def download(export)
# Upon failure a Zoura::Fault will be raised.
# @raise [Zuora::Fault]
def authenticate!
response = client.call(:login) do
message username: Zuora::Api.instance.config.username,
password: Zuora::Api.instance.config.password
end
response = client.call(:login, message: { username: config.username, password: config.password })

self.session = Zuora::Session.generate(response.to_hash)
client.globals.soap_header({'env:SessionHeader' => {'ins0:Session' => self.session.try(:key) }})
rescue Savon::SOAPFault => e
rescue Savon::SOAPFault, IOError => e
raise Zuora::Fault.new(:message => e.message)
end

private

def initialize
@config = Config.new
end

def make_client
Savon.client(wsdl: fetch_wsdl, soap_version: SOAP_VERSION, log: config.log || true, ssl_verify_mode: :none)
end

def fetch_wsdl
config&.wsdl_path || WSDL
def client
return @client if @client

@client = Savon.client(
wsdl: config&.wsdl_path ? config.wsdl_path : File.expand_path('../../../wsdl/zuora.a.38.0.wsdl', __FILE__),
ssl_verify_mode: :none,
soap_version: SOAP_VERSION,
log: config&.log || true,
filters: [:password]
)
end
end

# Support request tracking via notify
Savon.observers << Api.instance
end
26 changes: 15 additions & 11 deletions lib/zuora/attributes.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module Zuora
module Attributes

def self.included(base)
base.send(:include, ActiveModel::Naming)
base.send(:include, ActiveModel::Conversion)
Expand Down Expand Up @@ -40,17 +39,22 @@ def define_attributes(&block)
# generate association overrides for complex object handling
# and cache the objects so that they may be modified and updated
class_variable_get(:@@complex_attributes).each do |var, scope|
# set up the instance variable for the new assoc collection
# for new records, but call the original one for existing
# records and cache/return the result for subsequent calls.
class_eval <<~EVAL
prepend(Module.new do
def #{scope}
if new_record? || @#{scope}_cached
@#{scope} ||= []
else
@#{scope}_cached = true
@#{scope} = super
prepend(
Module.new do
def #{scope}
if new_record? || @#{scope}_cached
@#{scope} ||= []
else
@#{scope}_cached = true
@#{scope} = super
end
end
end
end)
)
EVAL
end
end
Expand Down Expand Up @@ -142,7 +146,7 @@ def remote_name
def inherited(subclass)
super
xpath = "//xs:complexType[@name='#{subclass.remote_name}']//xs:sequence/xs:element"
document = Zuora::Api.instance.wsdl.parser.instance_variable_get('@document')
document = Zuora::Api.instance.client.wsdl.parser.instance_variable_get('@document')
q = document.xpath(xpath, 's0' => 'http://schemas.xmlsoap.org/wsdl/', 'xs' => 'http://www.w3.org/2001/XMLSchema')
wsdl_attrs = (q.map{|e| e.attributes['name'].to_s.underscore.to_sym }) << :id
subclass.send(:class_variable_set, :@@wsdl_attributes, wsdl_attrs)
Expand Down Expand Up @@ -217,4 +221,4 @@ def remote_name
self.class.name.base_name
end
end
end
end
3 changes: 2 additions & 1 deletion lib/zuora/objects/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Account < Base
validates_inclusion_of :payment_term, :in => ['Due Upon Receipt','Net 15','Net 30','Net 45','Net 90']
validates_inclusion_of :batch, :in => (1..20).map{|n| "Batch#{n}" }
validates_inclusion_of :bcd_setting_option, :in => ['AutoSet','ManualSet'], :allow_nil => true
validates_inclusion_of :bill_cycle_day, :in => (1..31).to_a + (1..31).map(&:to_s)
validates_inclusion_of :bill_cycle_day, :in => (1..30).to_a + (1..30).map(&:to_s)
validates_inclusion_of :status, :in => ['Draft','Active','Canceled'], :allow_nil => true

define_attributes do
Expand All @@ -30,3 +30,4 @@ class Account < Base
end
end
end

39 changes: 20 additions & 19 deletions lib/zuora/objects/amendment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ module Zuora::Objects
class Amendment < Base
belongs_to :subscription

validates_presence_of :subscription_id, :name
validates_length_of :name, :maximum => 100
validates_inclusion_of :auto_renew, :in => [true, false], :allow_nil => true
validates_length_of :code, :maximum => 50, :allow_nil => true
validates_date_of :contract_effective_date, :allow_nil => true
validates_date_of :customer_acceptance_date, :allow_nil => true
validates_date_of :effective_date, :allow_nil => true
validates_date_of :service_activation_date, :if => Proc.new { |a| a.status == 'PendingAcceptance' }
validates_length_of :description, :maximum => 500, :allow_nil => true
validates_presence_of :subscription_id, :name
validates_length_of :name, :maximum => 100
validates_inclusion_of :auto_renew, :in => [true, false], :allow_nil => true
validates_length_of :code, :maximum => 50, :allow_nil => true
validates_datetime_of :contract_effective_date, :allow_nil => true
validates_datetime_of :customer_acceptance_date, :allow_nil => true
validates_datetime_of :effective_date, :allow_nil => true
validates_datetime_of :service_activation_date, :if => Proc.new { |a| a.status == 'PendingAcceptance' }
validates_length_of :description, :maximum => 500, :allow_nil => true
validates_numericality_of :initial_term, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
validates_numericality_of :renewal_term, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
validates_date_of :term_start_date, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
validates_presence_of :destination_account_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
validates_presence_of :destination_invoice_owner_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
validates_inclusion_of :status, :in => ["Completed", "Cancelled", "Draft", "Pending Acceptance", "Pending Activation"]
validates_inclusion_of :term_type, :in => ['TERMED', 'EVERGREEN'], :allow_nil => true
validates_inclusion_of :type, :in => ['Cancellation', 'NewProduct', 'OwnerTransfer', 'RemoveProduct', 'Renewal', 'UpdateProduct', 'TermsAndConditions']
validates_presence_of :rate_plan_data, :if => Proc.new { |a| ['NewProduct', 'RemoveProduct', 'UpdateProduct'].include?(a.type) }, :only => :apply_percentage_discount
validates_date_of :term_start_date, :if => Proc.new { |a| a.type == 'TermsAndConditions' }
validates_presence_of :destination_account_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
validates_presence_of :destination_invoice_owner_id, :if => Proc.new {|a| a.type == 'OwnerTransfer' }
validates_inclusion_of :status, :in => ["Completed", "Cancelled", "Draft", "Pending Acceptance", "Pending Activation"]
validates_inclusion_of :term_type, :in => ['TERMED', 'EVERGREEN'], :allow_nil => true
validates_inclusion_of :type, :in => ['Cancellation', 'NewProduct', 'OwnerTransfer', 'RemoveProduct', 'Renewal', 'UpdateProduct', 'TermsAndConditions']
validates_presence_of :rate_plan_data, :if => Proc.new { |a| ['NewProduct', 'RemoveProduct', 'UpdateProduct'].include?(a.type) }, :only => :apply_percentage_discount

attr_accessor :amendment_ids
attr_accessor :invoice_id
Expand All @@ -32,10 +32,12 @@ class Amendment < Base

def apply_percentage_discount
self.status = 'Completed'
result = self.connector.amend
result = self.connector.amend({ 'process_payments' => false })
apply_percentage_discount_response(result.to_hash, :amend_response)
end

private

def apply_percentage_discount_response(response_hash, type)
result = response_hash[type][:results]
if result[:success]
Expand All @@ -46,8 +48,7 @@ def apply_percentage_discount_response(response_hash, type)
clear_changes_information
return true
else
self.errors.add(:base, result[:errors][:message])
return false
raise StandardError.new(result[:errors][:message])
end
end
end
Expand Down
26 changes: 3 additions & 23 deletions lib/zuora/objects/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ class Base
# generate a new instance of a Zuora object
def initialize(attrs={}, &block)
apply_default_attributes
self.attributes = attrs
yield self if block_given?
end

def attributes=(attrs={})
attrs.each do |name, value|
self.send("#{name.to_s.underscore}=", value)
end
yield self if block_given?
end

# given a soap response hash, initialize a record
Expand Down Expand Up @@ -55,7 +51,7 @@ def self.unselectable_attributes
end

def self.namespace(uri)
Zuora::Api.instance.client.operation(:query).build.send(:namespace_by_uri, uri)
connector.current_client.client.operation(:query).build.send(:namespace_by_uri, uri)
end

def self.zns
Expand All @@ -80,24 +76,14 @@ def self.select(select)
self
end

# retrieve all of the records
def self.all
keys = (attributes - unselectable_attributes).map(&:to_s).map(&:zuora_camelize)
sql = "select #{keys.join(', ')} from #{remote_name}"

result = self.connector.query(sql)

generate(result.to_hash, :query_response)
end

# locate objects using a custom where clause, currently arel
# is not supported as it requires an actual db connection to
# generate the sql queries. This may be overcome in the future.
def self.where(where)
keys = self.select_attributes
if where.is_a?(Hash)
# FIXME: improper inject usage.
where = where.inject([]){|t,v| t << "#{v[0].to_s.zuora_camelize} = '#{v[1]}'"}.sort.join(' and ')
where = where.inject([]){|t,v| t << "#{v[0].to_s.camelcase} = '#{v[1]}'"}.sort.join(' and ')
end
sql = "select #{keys.join(', ')} from #{remote_name} where #{where}"

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

def self.query(query_string)
result = self.connector.query(query_string)
generate(result.to_hash, :query_response)
end

# has this record not been saved?
def new_record?
id.nil?
Expand Down Expand Up @@ -205,4 +186,3 @@ def self.select_attributes

end
end

36 changes: 18 additions & 18 deletions lib/zuora/objects/credit_balance_adjustment.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
module Zuora::Objects
class CreditBalanceAdjustment < Base
belongs_to :account
belongs_to :source_transaction
#module Zuora::Objects
#class CreditBalanceAdjustment < Base
#belongs_to :account
#belongs_to :source_transaction

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

define_attributes do
read_only :created_by_id, :created_date, :updated_by_id, :updated_date
end
end
end
#define_attributes do
#read_only :created_by_id, :created_date, :updated_by_id, :updated_date
#end
#end
#end
6 changes: 3 additions & 3 deletions lib/zuora/objects/invoice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class Invoice < Base
validates_numericality_of :amount
validates_numericality_of :balance, :allow_nil => true
validates_length_of :comments, :maximum => 255
validates_date_of :due_date
validates_date_of :invoice_date
validates_datetime_of :due_date
validates_datetime_of :invoice_date
validates_inclusion_of :includes_one_time, :in => [true, false]
validates_inclusion_of :includes_recurring, :in => [true, false]
validates_inclusion_of :includes_usage, :in => [true, false]
Expand All @@ -26,7 +26,7 @@ class Invoice < Base
validates_datetime_of :posted_date, :allow_nil => true
validates_numericality_of :refund_amount, :allow_nil => true
validates_inclusion_of :status, :in => %w(Canceled Draft Error Posted), :allow_nil => true
validates_date_of :target_date
validates_datetime_of :target_date
validates_inclusion_of :transferred_to_accounting, :in => %w(Processing Yes Error Ignore), :allow_nil => true
validates_datetime_of :updated_date

Expand Down
Loading

0 comments on commit 333589a

Please sign in to comment.