Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #2 from Sage/direct_debit_integration

Direct debit integration
  • Loading branch information...
commit 4edfffe7191ac6d04638abb939b1addc2b29636b 2 parents f4a6e2c + 6c32ad4
@whilefalse whilefalse authored
View
6 README.md
@@ -49,7 +49,7 @@ All additional requirements for development should be referenced in the provided
To set your connector:
- Zuora::Base.connector_class = Zuora::YourChosenConnector
+ Zuora::Objects::Base.connector_class = Zuora::YourChosenConnector
### Default SOAPConnector
This one is for normal usage, and is configured in the usual way. You do not need to explicitly
@@ -60,7 +60,7 @@ All additional requirements for development should be referenced in the provided
ZObjects, but within an in memory SQLite database. To use this:
require 'zuora/sqlite_connector'
- Zuora::Base.connector_class = Zuora::SqliteConnector
+ Zuora::Objects::Base.connector_class = Zuora::SqliteConnector
Zuora::SqliteConnector.build_schema #Builds the sqlite schema from the ZObjects defined
### Multiple Config SOAPConnector
@@ -68,7 +68,7 @@ All additional requirements for development should be referenced in the provided
allows you to specify within a block which config to use. This is done per-thread, so will
not effect other requests.
- Zuora::Base.connector_class = Zuora::MultiSoapConnector
+ Zuora::Objects::Base.connector_class = Zuora::MultiSoapConnector
# Note we don't use Zuora.configure, as that's global:
Zuora::MultiSoapConnector.configure :named_config, :username => 'u', :password => 'p'
View
17 lib/zuora/api.rb
@@ -28,8 +28,6 @@ class Api
# @return [Zuora::Config]
attr_accessor :config
- WSDL = File.expand_path('../../../wsdl/zuora.a.38.0.wsdl', __FILE__)
-
def self.instance
@instance ||= new
end
@@ -64,6 +62,7 @@ def request(method, xml_body=nil, &block)
soap.body = xml_body
end
end
+
rescue Savon::SOAP::Fault, IOError => e
raise Zuora::Fault.new(:message => e.message)
end
@@ -85,15 +84,21 @@ def authenticate!
raise Zuora::Fault.new(:message => e.message)
end
- private
+ def client
+ return @client if @client
- def initialize
Savon.configure do |savon|
savon.soap_version = 2
end
- self.client = Savon::Client.new do
- wsdl.document = WSDL
+ wsdl_path = if config && config.wsdl_path
+ config.wsdl_path
+ else
+ File.expand_path('../../../wsdl/zuora.a.38.0.wsdl', __FILE__)
+ end
+
+ @client = Savon::Client.new do
+ wsdl.document = wsdl_path
http.auth.ssl.verify_mode = :none
end
end
View
50 lib/zuora/objects.rb
@@ -1,30 +1,28 @@
module Zuora
module Objects
+ autoload :Base, 'zuora/objects/base'
+ autoload :Account, 'zuora/objects/account'
+ autoload :Contact, 'zuora/objects/contact'
+ autoload :Amendment, 'zuora/objects/amendment'
+ autoload :CommunicationProfile, 'zuora/objects/communication_profile'
+ # autoload :CreditBalanceAdjustment, 'zuora/objects/credit_balance_adjustment'
+ autoload :Invoice, 'zuora/objects/invoice'
+ autoload :InvoiceAdjustment, 'zuora/objects/invoice_adjustment'
+ autoload :InvoiceItem, 'zuora/objects/invoice_item'
+ autoload :InvoiceItemAdjustment, 'zuora/objects/invoice_item_adjustment'
+ # autoload :InvoicePayment, 'zuora/objects/invoice_payment'
+ autoload :Usage, 'zuora/objects/usage'
+ autoload :SubscribeRequest, 'zuora/objects/subscribe_request'
+ autoload :Subscription, 'zuora/objects/subscription'
+ # autoload :Payment, 'zuora/objects/payment'
+ autoload :PaymentMethod, 'zuora/objects/payment_method'
+ autoload :Product, 'zuora/objects/product'
+ autoload :ProductRatePlan, 'zuora/objects/product_rate_plan'
+ autoload :ProductRatePlanCharge, 'zuora/objects/product_rate_plan_charge'
+ autoload :ProductRatePlanChargeTier, 'zuora/objects/product_rate_plan_charge_tier'
+ autoload :RatePlan, 'zuora/objects/rate_plan'
+ autoload :RatePlanCharge, 'zuora/objects/rate_plan_charge'
+ autoload :RatePlanChargeTier, 'zuora/objects/rate_plan_charge_tier'
+ # autoload :Refund, 'zuora/objects/refund'
end
end
-
-require 'zuora/objects/base'
-require 'zuora/objects/account'
-require 'zuora/objects/contact'
-require 'zuora/objects/amendment'
-require 'zuora/objects/communication_profile'
-require 'zuora/objects/credit_balance_adjustment'
-require 'zuora/objects/invoice'
-require 'zuora/objects/invoice_adjustment'
-require 'zuora/objects/invoice_item'
-require 'zuora/objects/invoice_item_adjustment'
-require 'zuora/objects/invoice_payment'
-require 'zuora/objects/usage'
-require 'zuora/objects/subscribe_request'
-require 'zuora/objects/subscription'
-require 'zuora/objects/payment'
-require 'zuora/objects/payment_method'
-require 'zuora/objects/product'
-require 'zuora/objects/product_rate_plan'
-require 'zuora/objects/product_rate_plan_charge'
-require 'zuora/objects/product_rate_plan_charge_tier'
-require 'zuora/objects/rate_plan'
-require 'zuora/objects/rate_plan_charge'
-require 'zuora/objects/rate_plan_charge_tier'
-require 'zuora/objects/refund'
-require 'zuora/objects/refund_invoice_payment'
View
2  lib/zuora/objects/account.rb
@@ -10,7 +10,7 @@ class Account < Base
validates_presence_of :account_number, :name, :status, :payment_term, :batch, :currency
validates_length_of :name, :maximum => 50
validates_length_of :purchase_order_number, :maximum => 100, :allow_nil => true
- validates_inclusion_of :payment_term, :in => ['Due Upon Receipt','Net 30','Net 45','Net 90']
+ 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..30).to_a + (1..30).map(&:to_s)
View
2  lib/zuora/objects/contact.rb
@@ -2,7 +2,7 @@ module Zuora::Objects
class Contact < Base
belongs_to :account
- validates_presence_of :account_id, :first_name, :last_name
+ validates_presence_of :first_name, :last_name
validates_length_of :first_name, :maximum => 100
validates_length_of :last_name, :maximum => 100
validates_length_of :nick_name, :maximum => 100, :allow_nil => true
View
4 lib/zuora/objects/payment_method.rb
@@ -2,10 +2,10 @@ module Zuora::Objects
class PaymentMethod < Base
belongs_to :account
- validates_presence_of :account_id
+ # validates_presence_of :account_id
# Generic Validations
- validates_inclusion_of :type, :in => %w(ACH Cash Check CreditCard CreditCardReferenceTransaction DebitCard Other PayPal WireTransfer)
+ validates_inclusion_of :type, :in => %w(ACH BankTransfer Cash Check CreditCard CreditCardReferenceTransaction DebitCard Other PayPal WireTransfer)
validates_length_of :device_session_id, :maximum => 255, :allow_nil => true
validates_length_of :email, :maximum => 80, :allow_nil => true
validates_length_of :ip_address, :maximum => 15, :allow_nil => true
View
92 lib/zuora/objects/subscribe_request.rb
@@ -36,42 +36,8 @@ def must_have_usable(ref)
# Generate a subscription request
def create
- return false unless valid?
- result = connector.current_client.request(:subscribe) do |xml|
- xml.__send__(zns, :subscribes) do |s|
- s.__send__(zns, :Account) do |a|
- generate_account(a)
- end
-
- s.__send__(zns, :SubscribeOptions) do |so|
- generate_subscribe_options(so)
- end unless subscribe_options.blank?
-
- s.__send__(zns, :PaymentMethod) do |pm|
- generate_payment_method(pm)
- end
-
- s.__send__(zns, :BillToContact) do |btc|
- generate_bill_to_contact(btc)
- end
-
- s.__send__(zns, :SoldToContact) do |btc|
- generate_sold_to_contact(btc)
- end unless sold_to_contact.nil?
-
- s.__send__(zns, :SubscriptionData) do |sd|
- sd.__send__(zns, :Subscription) do |sub|
- generate_subscription(sub)
- end
-
- sd.__send__(zns, :RatePlanData) do |rpd|
- rpd.__send__(zns, :RatePlan) do |rp|
- rp.__send__(ons, :ProductRatePlanId, product_rate_plan.id)
- end
- end
- end
- end
- end
+ # return false unless valid?
+ result = connector.subscribe
apply_response(result.to_hash, :subscribe_response)
end
@@ -90,59 +56,7 @@ def apply_response(response_hash, type)
return false
end
end
-
- def generate_bill_to_contact(builder)
- if bill_to_contact.new_record?
- bill_to_contact.to_hash.each do |k,v|
- builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
- end
- else
- builder.__send__(ons, :Id, bill_to_contact.id)
- end
- end
-
- def generate_sold_to_contact(builder)
- if sold_to_contact.new_record?
- sold_to_contact.to_hash.each do |k,v|
- builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
- end
- else
- builder.__send__(ons, :Id, sold_to_contact.id)
- end
- end
-
- def generate_account(builder)
- if account.new_record?
- account.to_hash.each do |k,v|
- builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
- end
- else
- builder.__send__(ons, :Id, account.id)
- end
- end
-
- def generate_payment_method(builder)
- if payment_method.new_record?
- payment_method.to_hash.each do |k,v|
- builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
- end
- else
- builder.__send__(ons, :Id, payment_method.id)
- end
- end
-
- def generate_subscription(builder)
- subscription.to_hash.each do |k,v|
- builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
- end
- end
-
- def generate_subscribe_options(builder)
- subscribe_options.each do |k,v|
- builder.__send__(ons, k.to_s.camelize.to_sym, v)
- end
- end
-
+ #
# TODO: Restructute an intermediate class that includes
# persistence only within ZObject models.
# These methods are not relevant, but defined in Base
View
2  lib/zuora/objects/subscription.rb
@@ -7,7 +7,7 @@ class Subscription < Base
has_many :rate_plans
validates_presence_of :contract_effective_date, :initial_term,
- :renewal_term, :term_start_date
+ :renewal_term
validates_inclusion_of :auto_renew, :in => [true, false]
validates_datetime_of :cancelled_date, :allow_nil => true
View
91 lib/zuora/soap_connector.rb
@@ -46,6 +46,44 @@ def destroy
end
end
+ def subscribe
+ current_client.request(:subscribe) do |xml|
+ xml.__send__(zns, :subscribes) do |s|
+ s.__send__(zns, :Account) do |a|
+ generate_account(a)
+ end
+
+ s.__send__(zns, :PaymentMethod) do |pm|
+ generate_payment_method(pm)
+ end unless @model.payment_method.nil?
+
+ s.__send__(zns, :BillToContact) do |btc|
+ generate_bill_to_contact(btc)
+ end unless @model.bill_to_contact.nil?
+
+ s.__send__(zns, :SoldToContact) do |btc|
+ generate_sold_to_contact(btc)
+ end unless @model.sold_to_contact.nil?
+
+ s.__send__(zns, :SubscribeOptions) do |so|
+ generate_subscribe_options(so)
+ end unless @model.subscribe_options.blank?
+
+ s.__send__(zns, :SubscriptionData) do |sd|
+ sd.__send__(zns, :Subscription) do |sub|
+ generate_subscription(sub)
+ end
+
+ sd.__send__(zns, :RatePlanData) do |rpd|
+ rpd.__send__(zns, :RatePlan) do |rp|
+ rp.__send__(ons, :ProductRatePlanId, @model.product_rate_plan.id)
+ end
+ end
+ end
+ end
+ end
+ end
+
# Remove empty attributes from response hash
# and typecast any known types from the wsdl
def parse_attributes(type, attrs={})
@@ -106,5 +144,58 @@ def generate_complex_objects(builder, action)
end
end
end
+
+ def generate_bill_to_contact(builder)
+ if @model.bill_to_contact.new_record?
+ @model.bill_to_contact.to_hash.each do |k,v|
+ builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
+ end
+ else
+ builder.__send__(ons, :Id, @model.bill_to_contact.id)
+ end
+ end
+
+ def generate_sold_to_contact(builder)
+ if @model.sold_to_contact.new_record?
+ @model.sold_to_contact.to_hash.each do |k,v|
+ builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
+ end
+ else
+ builder.__send__(ons, :Id, @model.sold_to_contact.id)
+ end
+ end
+
+ def generate_account(builder)
+ if @model.account.new_record?
+ @model.account.to_hash.each do |k,v|
+ builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
+ end
+ else
+ builder.__send__(ons, :Id, @model.account.id)
+ end
+ end
+
+ def generate_payment_method(builder)
+ if @model.payment_method.new_record?
+ @model.payment_method.to_hash.each do |k,v|
+ builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
+ end
+ else
+ builder.__send__(ons, :Id, @model.payment_method.id)
+ end
+ end
+
+ def generate_subscription(builder)
+ @model.subscription.to_hash.each do |k,v|
+ builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
+ end
+ end
+
+ def generate_subscribe_options(builder)
+ @model.subscribe_options.each do |k,v|
+ builder.__send__(zns, k.to_s.camelize.to_sym, v)
+ end
+ end
+
end
end
View
35 lib/zuora/sqlite_connector.rb
@@ -86,6 +86,35 @@ def destroy
}
end
+ def subscribe
+ [
+ :account,
+ :subscription,
+ :bill_to_contact,
+ :payment_method,
+ :sold_to_contact,
+ :product_rate_plan
+ ].each do |relation|
+ obj = @model.send(relation)
+ if obj
+ if obj.new_record?
+ obj.create
+ else
+ obj.update
+ end
+ end
+ end
+
+ {
+ :subscribe_response => {
+ :result => {
+ :success => true,
+ :id => nil
+ }
+ }
+ }
+ end
+
def parse_attributes(type, attrs = {})
data = attrs.to_a.map do |a|
key, value = a
@@ -111,8 +140,8 @@ def hash_result_row(row, result)
end
def self.generate_tables
- Zuora::Objects::Base.subclasses.each do |model|
- create_table(model)
+ Zuora::Objects.constants.select { |c| c != :Base }.each do |model|
+ create_table(Zuora::Objects.const_get(model))
end
end
@@ -122,7 +151,7 @@ def self.create_table(model)
attributes = attributes.map do |a|
"'#{a.to_s.camelize}' text"
end
- autoid = "'Id' integer PRIMARY KEY AUTOINCREMENT"
+ autoid = "'Id' integer primary key"
attributes.unshift autoid
attributes = attributes.join(", ")
schema = "CREATE TABLE 'main'.'#{table_name}' (#{attributes});"
View
6 spec/zuora/api_spec.rb
@@ -6,11 +6,7 @@
Zuora::Api.any_instance.stub(:authenticated?).and_return(true)
end
- it "has readable WSDL" do
- File.exists?(Zuora::Api::WSDL).should be
- end
-
- it "uses provided WSDL" do
+ it "uses provided wsdl_path" do
Zuora::Api.instance.client.wsdl.endpoint.to_s.should == "https://www.zuora.com/apps/services/a/38.0"
end
View
4 spec/zuora/objects/contact_spec.rb
@@ -20,10 +20,6 @@
subject.should_not be_valid
end
- it "requires account_id" do
- subject.errors[:account_id].should include("can't be blank")
- end
-
it "requires first_name" do
subject.errors[:first_name].should include("can't be blank")
end
View
2  spec/zuora/objects/subscribe_request_spec.rb
@@ -111,7 +111,7 @@
end
xml = Zuora::Api.instance.last_request
- xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:SubscribeOptions/#{ons}:GenerateInvoice").
+ xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:SubscribeOptions/#{zns}:GenerateInvoice").
with_value(true)
end
View
40 spec/zuora/sqlite_connector_spec.rb
@@ -118,16 +118,38 @@
end
end
- describe "factories" do
- before :each do
- @product = Factory(:product)
- end
-
- it "should exists" do
- @product.should be
- end
+ describe :subscribe do
+ before :each do
+ described_class.build_schema
+ @acc = Zuora::Objects::Account.new
+ @subscription = Zuora::Objects::Subscription.new
+ @bill_to_contact = Zuora::Objects::Contact.new
+ @payment_method = Zuora::Objects::PaymentMethod.new
+ @sold_to_contact = Zuora::Objects::Contact.new
+ @product_rate_plan = Zuora::Objects::ProductRatePlan.new
+
+ @model = Zuora::Objects::SubscribeRequest.new
+ @model.account = @acc
+ @model.subscription = @subscription
+ @model.bill_to_contact = @bill_to_contact
+ @model.payment_method = @payment_method
+ @model.sold_to_contact = @sold_to_contact
+ @model.product_rate_plan = @product_rate_plan
end
- end
+ it "calls create on all of the related objects" do
+ @acc.should_receive(:create)
+ @subscription.should_receive(:create)
+ @bill_to_contact.should_receive(:create)
+ @payment_method.should_receive(:create)
+ @sold_to_contact.should_receive(:create)
+ @product_rate_plan.should_receive(:create)
+
+ @model.stub(:valid?).and_return(true)
+ @model.create
+ end
+
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.