Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix v2.0.4 sage #31

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
angelasilva marked this conversation as resolved.
Show resolved Hide resolved

# @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,
ianoxley marked this conversation as resolved.
Show resolved Hide resolved
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
angelasilva marked this conversation as resolved.
Show resolved Hide resolved
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