Skip to content

Commit

Permalink
added amend_request and spec, and fixed subscribe_request
Browse files Browse the repository at this point in the history
  • Loading branch information
mdemin914 committed Oct 16, 2012
1 parent 097ed91 commit f1f15a4
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 13 deletions.
1 change: 1 addition & 0 deletions lib/zuora/objects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ module Objects
require 'zuora/objects/rate_plan_charge_tier'
require 'zuora/objects/refund'
require 'zuora/objects/refund_invoice_payment'
require 'zuora/objects/amend_request'
102 changes: 102 additions & 0 deletions lib/zuora/objects/amend_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
module Zuora::Objects
class AmendRequest < Base

attr_accessor :amendment
attr_accessor :plans_and_charges

store_accessors :amend_options
store_accessors :preview_options

attr_accessor :validation_errors

validate do |request|
self.validation_errors = Array.new
self.validation_errors << request.must_be_present(:amendment)
self.validation_errors << request.must_be_present(:plans_and_charges)
end

def must_be_present(ref)
obj = self.send(ref)
return errors[ref] << "#{ref} must be provided" if obj.nil?
end

# Generate an amend request
def create
return validation_errors unless valid?
result = Zuora::Api.instance.request(:amend) do |xml|
xml.__send__(zns, :requests) do |r|
r.__send__(zns, :Amendments) do |a|
generate_amendment a
generate_rate_plan_data a
end
r.__send__(zns, :PreviewOptions) do |so|
generate_preview_options(so)
end unless preview_options.blank?

r.__send__(zns, :AmendOptions) do |so|
generate_amend_options(so)
end unless amend_options.blank?
end
end
apply_response(result.to_hash, :amend_response)
end

protected

def apply_response(response_hash, type)
result = response_hash[type][:results]

end

def generate_amend_options(builder)
amend_options.each do |k,v|
builder.__send__(zns, k.to_s.zuora_camelize.to_sym, v)
end
end

def generate_preview_options(builder)
preview_options.each do |k,v|
builder.__send__(zns, k.to_s.zuora_camelize.to_sym, v)
end
end

def generate_amendment(builder)
amendment.to_hash.each do |k,v|
if k.to_s != 'rate_plan_data'
builder.__send__(zns, k.to_s.zuora_camelize.to_sym, v) unless v.nil?
end
end
end

def generate_rate_plan_data(builder)

self.plans_and_charges.each do |pandc|
rate_plan = pandc[:rate_plan]
charges = pandc[:charges]

builder.__send__(ons, :RatePlanData) do |rpd|
rpd.__send__(ons, :RatePlan) do |rp|
rp.__send__(ons, :ProductRatePlanId, rate_plan.id)
end
charges.each do |charge|
rpd.__send__(zns, :RatePlanChargeData) do |rpcd|
rpcd.__send__(zns, :RatePlanCharge) do |rpc|
rpc.__send__(ons, :ProductRatePlanChargeId, charge.product_rate_plan_charge_id)
rpc.__send__(ons, :Quantity, charge.quantity)
end
end
end unless charges == nil
end
end
end

# TODO: Restructute an intermediate class that includes
# persistence only within ZObject models.
# These methods are not relevant, but defined in Base
def find ; end
def where ; end
def update ; end
def destroy ; end
def save ; end
end
end
22 changes: 11 additions & 11 deletions lib/zuora/objects/subscribe_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,27 @@ class SubscribeRequest < Base
# used to validate nested objects
def must_have_new(ref)
obj = self.send(ref)
return errors[ref] << "must be provided" if obj.nil?
return errors[ref] << "must be new" unless obj.new_record?
return errors[ref] << "#{ref} must be provided" if obj.nil?
return errors[ref] << "#{ref} must be new" unless obj.new_record?
must_have_usable(ref)
end

# used to validate nested objects
def must_have_usable(ref)
obj = self.send(ref)
return errors[ref] << "must be provided" if obj.nil?
return errors[ref] << "#{ref} must be provided" if obj.nil?
obj = obj.is_a?(Array) ? obj : [obj]
obj.each do |object|
if object.new_record? || object.changed?
errors[ref] << "is invalid" unless object.valid?
errors[ref] << "#{ref} is invalid" unless object.valid?
end
end
return errors
end

# Generate a subscription request
def create
return false unless valid?
return validation_errors unless valid?
result = Zuora::Api.instance.request(:subscribe) do |xml|
xml.__send__(zns, :subscribes) do |s|
s.__send__(zns, :Account) do |a|
Expand Down Expand Up @@ -136,7 +136,7 @@ def apply_response(response_hash, type)
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?
builder.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil?
end
else
builder.__send__(ons, :Id, bill_to_contact.id)
Expand All @@ -146,7 +146,7 @@ def generate_bill_to_contact(builder)
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?
builder.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil?
end
else
builder.__send__(ons, :Id, sold_to_contact.id)
Expand All @@ -156,7 +156,7 @@ def generate_sold_to_contact(builder)
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?
builder.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil?
end
else
builder.__send__(ons, :Id, account.id)
Expand All @@ -166,7 +166,7 @@ def generate_account(builder)
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?
builder.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil?
end
else
builder.__send__(ons, :Id, payment_method.id)
Expand All @@ -175,13 +175,13 @@ def generate_payment_method(builder)

def generate_subscription(builder)
subscription.to_hash.each do |k,v|
builder.__send__(ons, k.to_s.camelize.to_sym, v) unless v.nil?
builder.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil?
end
end

def generate_subscribe_options(builder)
subscribe_options.each do |k,v|
builder.__send__(zns, k.to_s.camelize.to_sym, v)
builder.__send__(zns, k.to_s.zuora_camelize.to_sym, v)
end
end

Expand Down
11 changes: 11 additions & 0 deletions spec/factories/amendments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FactoryGirl.define do
factory :amendment, :class => Zuora::Objects::Amendment do
contract_effective_date DateTime.now
service_activation_date DateTime.now
customer_acceptance_date DateTime.now
sequence(:name){|n| "Example Amendment #{n}"}
term_start_date DateTime.now
type "NewProduct"
status "Active"
end
end
1 change: 1 addition & 0 deletions spec/fixtures/responses/amend_request_failure.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:amendResponse xmlns:ns1="http://api.zuora.com/"><ns1:results><ns1:Errors><ns1:Code>INVALID_VALUE</ns1:Code><ns1:Message>Invalid value for field SubscriptionId: 2c92c0f93a569878013a6778f0446b11</ns1:Message></ns1:Errors><ns1:Success>false</ns1:Success></ns1:results></ns1:amendResponse></soapenv:Body></soapenv:Envelope>
1 change: 1 addition & 0 deletions spec/fixtures/responses/amend_request_success.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:amendResponse xmlns:ns1="http://api.zuora.com/"><ns1:results><ns1:AmendmentIds>2c92c0f83a569221013a6803e17c529e</ns1:AmendmentIds><ns1:Success>true</ns1:Success></ns1:results></ns1:amendResponse></soapenv:Body></soapenv:Envelope>
2 changes: 1 addition & 1 deletion spec/fixtures/responses/subscribe_request_success.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns1:subscribeResponse xmlns:ns1="http://api.zuora.com/"><ns1:result><ns1:AccountId>4028e48734aa0ffc0134c9fcd9a71d40</ns1:AccountId><ns1:AccountNumber>8d8bff8493905397c37dc0123e215f21</ns1:AccountNumber><ns1:InvoiceId>4028e48834aa10a30134c9fce1016771</ns1:InvoiceId><ns1:InvoiceNumber>INV00000002</ns1:InvoiceNumber><ns1:InvoiceResult><ns1:Invoice xmlns:ns2="http://object.api.zuora.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:Invoice"><ns2:Id>4028e48834aa10a30134c9fce1016771</ns2:Id><ns2:InvoiceNumber>INV00000002</ns2:InvoiceNumber></ns1:Invoice></ns1:InvoiceResult><ns1:SubscriptionId>4028e48834aa10a30134c9fcdf9f6764</ns1:SubscriptionId><ns1:SubscriptionNumber>Example Subscription 1</ns1:SubscriptionNumber><ns1:Success>true</ns1:Success></ns1:result></ns1:subscribeResponse></soapenv:Body></soapenv:Envelope>
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns1:subscribeResponse xmlns:ns1="http://api.zuora.com/"><ns1:result><ns1:AccountId>4028e48734aa0ffc0134c9fcd9a71d40</ns1:AccountId><ns1:AccountNumber>8d8bff8493905397c37dc0123e215f21</ns1:AccountNumber><ns1:InvoiceId>4028e48834aa10a30134c9fce1016771</ns1:InvoiceId><ns1:InvoiceNumber>INV00000002</ns1:InvoiceNumber><ns1:InvoiceResult><ns1:Invoice xmlns:ns2="http://object.api.zuora.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:Invoice"><ns2:Id>4028e48834aa10a30134c9fce1016771</ns2:Id><ns2:InvoiceNumber>INV00000002</ns2:InvoiceNumber></ns1:Invoice></ns1:InvoiceResult><ns1:SubscriptionId>4028e48834aa10a30134c9fcdf9f6764</ns1:SubscriptionId><ns1:SubscriptionNumber>Example Subscription 1</ns1:SubscriptionNumber><ns1:Success>true</ns1:Success></ns1:result></ns1:subscribeResponse></soapenv:Body></soapenv:Envelope>
103 changes: 103 additions & 0 deletions spec/zuora/objects/amend_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
require 'spec_helper'

describe Zuora::Objects::AmendRequest do

describe "most persistence methods" do
it "are not publicly available" do
[:update, :destroy, :where, :find].each do |meth|
subject.public_methods.should_not include(meth)
end
end
end

describe "generating a request" do
before do
subscription = FactoryGirl.build(:subscription)
@amendment = FactoryGirl.build(:amendment)
@amendment.subscription_id = subscription.id
MockResponse.responds_with(:payment_method_credit_card_find_success) do
@product_rate_plans = [Zuora::Objects::ProductRatePlan.find('stub')]
end
end

it "provides properly formatted xml when using existing objects" do
MockResponse.responds_with(:amend_request_success) do
subject.amendment = @amendment
subject.plans_and_charges = Array.new << { rate_plan: @product_rate_plans[0], charges: nil }
amnd_resp = subject.create
amnd_resp[:success].should == true
end

xml = Zuora::Api.instance.last_request
xml.should have_xml("//env:Body/#{zns}:amend/#{zns}:requests/#{zns}:Amendments/#{zns}:Type").
with_value('NewProduct')
xml.should have_xml("//env:Body/#{zns}:amend/#{zns}:requests/#{zns}:Amendments/#{zns}:Name").
with_value('Example Amendment 1')
xml.should have_xml("//env:Body/#{zns}:amend/#{zns}:requests/#{zns}:Amendments/#{ons}:RatePlanData/#{ons}:RatePlan/#{ons}:ProductRatePlanId").
with_value('4028e48834aa10a30134c50f40901ea7')
end

it "handles applying amend failures messages" do
MockResponse.responds_with(:amend_request_failure) do
@amendment.subscription_id = '2c92c0f93a569878013a6778f0446b11'
subject.amendment = @amendment
subject.plans_and_charges = Array.new << { rate_plan: @product_rate_plans[0], charges: nil }
amnd_resp = subject.create
amnd_resp[:success].should == false
amnd_resp[:errors][:message].should include('Invalid value for field SubscriptionId: 2c92c0f93a569878013a6778f0446b11')
end
end

it "supports amend options" do
MockResponse.responds_with(:amend_request_success) do
subject.amendment = @amendment
subject.plans_and_charges = Array.new << { rate_plan: @product_rate_plans[0], charges: nil }
subject.amend_options = {:generate_invoice => true, :process_payments => true}
amnd_resp = subject.create
amnd_resp[:success].should == true
end

xml = Zuora::Api.instance.last_request
xml.should have_xml("//env:Body/#{zns}:amend/#{zns}:requests/#{zns}:AmendOptions/#{zns}:GenerateInvoice").
with_value(true)
end

it "supports preview options" do
MockResponse.responds_with(:amend_request_success) do
subject.amendment = @amendment
subject.plans_and_charges = Array.new << { rate_plan: @product_rate_plans[0], charges: nil }
subject.preview_options = { enable_preview_mode: true, number_of_periods: 1 }
amnd_resp = subject.create
amnd_resp[:success].should == true
end

xml = Zuora::Api.instance.last_request
xml.should have_xml("//env:Body/#{zns}:amend/#{zns}:requests/#{zns}:PreviewOptions/#{zns}:EnablePreviewMode").
with_value(true)
end

it "supports multiple rate plans with multiple charges" do
MockResponse.responds_with(:amend_request_success) do

rpc = Zuora::Objects::RatePlanCharge.new
rpc.quantity = 12
rpc.product_rate_plan_charge_id = '123'

rp = Zuora::Objects::ProductRatePlan.new
rp.id = @product_rate_plans[0].id

pandc = Array.new
pandc << {rate_plan: rp, charges: [rpc]}
pandc << {rate_plan: rp, charges: [rpc]}
subject.amendment = @amendment
subject.plans_and_charges = pandc
subject.should be_valid
sub_resp = subject.create
sub_resp[:success].should == true
end
xml = Zuora::Api.instance.last_request
xml.should have_xml("//env:Body/#{zns}:amend/#{zns}:requests/#{zns}:Amendments/#{ons}:RatePlanData")
end

end
end
2 changes: 1 addition & 1 deletion spec/zuora/objects/subscribe_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@

it "supports subscription options" do
MockResponse.responds_with(:subscribe_request_success) do
subject.subscribe_options = {:generate_invoice => true, :process_payments => true}
subject.subscribe_options = { generate_invoice: true, process_payments: true }
subject.should be_valid
sub_resp = subject.create
sub_resp[:success].should == true
Expand Down

0 comments on commit f1f15a4

Please sign in to comment.