active_zuora 1.3.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.octopolo.yml +4 -0
- data/.soyuz.yml +13 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.markdown +41 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +191 -0
- data/Rakefile +9 -53
- data/TODO.md +2 -0
- data/active_zuora.gemspec +25 -59
- data/lib/active_zuora.rb +44 -12
- data/lib/active_zuora/amend.rb +43 -0
- data/lib/active_zuora/base.rb +84 -0
- data/lib/active_zuora/batch_subscribe.rb +53 -0
- data/lib/active_zuora/belongs_to_associations.rb +56 -0
- data/lib/active_zuora/billing_preview.rb +49 -0
- data/lib/active_zuora/collection_proxy.rb +38 -0
- data/lib/active_zuora/connection.rb +47 -0
- data/lib/active_zuora/fields.rb +129 -0
- data/lib/active_zuora/fields/array_field_decorator.rb +28 -0
- data/lib/active_zuora/fields/boolean_field.rb +12 -0
- data/lib/active_zuora/fields/date_field.rb +18 -0
- data/lib/active_zuora/fields/date_time_field.rb +19 -0
- data/lib/active_zuora/fields/decimal_field.rb +12 -0
- data/lib/active_zuora/fields/field.rb +76 -0
- data/lib/active_zuora/fields/integer_field.rb +11 -0
- data/lib/active_zuora/fields/object_field.rb +31 -0
- data/lib/active_zuora/fields/string_field.rb +11 -0
- data/lib/active_zuora/generate.rb +43 -0
- data/lib/active_zuora/generator.rb +244 -0
- data/lib/active_zuora/has_many_associations.rb +37 -0
- data/lib/active_zuora/has_many_proxy.rb +50 -0
- data/lib/active_zuora/lazy_attr.rb +52 -0
- data/lib/active_zuora/persistence.rb +172 -0
- data/lib/active_zuora/relation.rb +260 -0
- data/lib/active_zuora/scoping.rb +50 -0
- data/lib/active_zuora/subscribe.rb +42 -0
- data/lib/active_zuora/version.rb +3 -0
- data/lib/active_zuora/z_object.rb +21 -0
- data/spec/account_integration_spec.rb +41 -0
- data/spec/base_spec.rb +39 -0
- data/spec/belongs_to_associations_spec.rb +35 -0
- data/spec/collection_proxy_spec.rb +28 -0
- data/spec/connection_spec.rb +66 -0
- data/spec/fields/date_field_spec.rb +35 -0
- data/spec/has_many_integration_spec.rb +53 -0
- data/spec/lazy_attr_spec.rb +22 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/subscribe_integration_spec.rb +344 -0
- data/spec/zobject_integration_spec.rb +104 -0
- data/wsdl/zuora.wsdl +1548 -0
- metadata +141 -53
- data/LICENSE +0 -202
- data/README.rdoc +0 -15
- data/VERSION +0 -1
- data/custom_fields.yml +0 -17
- data/lib/zuora/ZUORA.rb +0 -1398
- data/lib/zuora/ZUORADriver.rb +0 -128
- data/lib/zuora/ZUORAMappingRegistry.rb +0 -1488
- data/lib/zuora/ZuoraServiceClient.rb +0 -124
- data/lib/zuora/account.rb +0 -4
- data/lib/zuora/api.rb +0 -18
- data/lib/zuora/contact.rb +0 -4
- data/lib/zuora/rate_plan.rb +0 -4
- data/lib/zuora/rate_plan_data.rb +0 -4
- data/lib/zuora/subscribe_options.rb +0 -4
- data/lib/zuora/subscribe_request.rb +0 -4
- data/lib/zuora/subscribe_with_existing_account_request.rb +0 -4
- data/lib/zuora/subscription.rb +0 -4
- data/lib/zuora/subscription_data.rb +0 -4
- data/lib/zuora/zobject.rb +0 -52
- data/lib/zuora_client.rb +0 -181
- data/lib/zuora_interface.rb +0 -199
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class ArrayFieldDecorator < SimpleDelegator
|
3
|
+
|
4
|
+
# Wraps a Field object and typecasts/builds
|
5
|
+
# item as an array of the given field.
|
6
|
+
|
7
|
+
def type_cast(values)
|
8
|
+
# Force into an array and run type_cast on each element.
|
9
|
+
[values].flatten.compact.map { |value| __getobj__.type_cast(value) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_xml(xml, soap, values, options={})
|
13
|
+
# It may be wierd that we're mapping and taking the last value,
|
14
|
+
# But there's an issue with xml builder where if a block
|
15
|
+
# returns an array, it will output the array in the XML.
|
16
|
+
# So instead, we'll have our block return the value
|
17
|
+
# of the last build_xml call.
|
18
|
+
[values].flatten.compact.map do |value|
|
19
|
+
__getobj__.build_xml(xml, soap, value, options)
|
20
|
+
end.last
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear_changed_attributes(values)
|
24
|
+
[values].flatten.compact.map { |value| __getobj__.clear_changed_attributes(value) }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class BooleanField < Field
|
3
|
+
|
4
|
+
def type_cast(value)
|
5
|
+
return value if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
6
|
+
return true if value.to_s.downcase == 'true'
|
7
|
+
return false if value.to_s.downcase == 'false'
|
8
|
+
default
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class DateField < Field
|
3
|
+
|
4
|
+
def type_cast(value)
|
5
|
+
return value if value.nil?
|
6
|
+
return value.to_date if value.is_a?(Date)
|
7
|
+
return value.to_date if value.is_a?(DateTime)
|
8
|
+
value.to_date rescue default
|
9
|
+
end
|
10
|
+
|
11
|
+
def build_xml(xml, soap, value, options={})
|
12
|
+
value = value ? value.strftime("%Y-%m-%d") : ''
|
13
|
+
super(xml, soap, value, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class DateTimeField < Field
|
3
|
+
|
4
|
+
def type_cast(value)
|
5
|
+
return value if value.nil? || value.is_a?(Date)
|
6
|
+
return value.to_datetime if value.is_a?(Time)
|
7
|
+
value.to_datetime rescue default
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_xml(xml, soap, value, options={})
|
11
|
+
# All dates need to be in PST time. Since all user-set attributes
|
12
|
+
# in Zuora are really only dates, we'll chop off the time.
|
13
|
+
# 2012-05-22T00:00:00-08:00
|
14
|
+
value = value ? value.strftime("%Y-%m-%dT00:00:00-08:00") : ''
|
15
|
+
super(xml, soap, value, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class Field
|
3
|
+
|
4
|
+
attr_accessor :name, :zuora_name, :default, :namespace
|
5
|
+
|
6
|
+
def initialize(name, namespace, options={})
|
7
|
+
@name = name.to_s
|
8
|
+
@namespace = namespace
|
9
|
+
@zuora_name = options[:zuora_name] || @name.camelize
|
10
|
+
@default = options[:default]
|
11
|
+
end
|
12
|
+
|
13
|
+
def type_cast(value)
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_instance_methods(zuora_class)
|
18
|
+
# We store this into a variable so we can use it in our
|
19
|
+
# class eval below.
|
20
|
+
field_name = name
|
21
|
+
# Add dirty helpers
|
22
|
+
# The value will still be stored in an instance
|
23
|
+
# variable with the name of the field.
|
24
|
+
# But we'll define extra writer methods so that we
|
25
|
+
# can handle any input from savon.
|
26
|
+
# Savon just calls underscore on the element names,
|
27
|
+
# but our fields allow for any combination
|
28
|
+
# of field name and Zuora name.
|
29
|
+
# This is especially useful for custom fields which
|
30
|
+
# are named like CustomField__c. You might choose
|
31
|
+
# to make this field :custom_field, and therefore
|
32
|
+
# we'll need a writer for :custom_field, :custom_field_c,
|
33
|
+
# and I threw in a :CustomField__c just for good measure.
|
34
|
+
writers = [field_name, zuora_name, zuora_name.underscore].uniq
|
35
|
+
zuora_class.class_eval do
|
36
|
+
# Define the methods on an included module, so we can override
|
37
|
+
# them using super.
|
38
|
+
generated_attribute_methods.module_eval do
|
39
|
+
# Getter
|
40
|
+
attr_reader field_name
|
41
|
+
# Boolean check.
|
42
|
+
define_method "#{field_name}?" do
|
43
|
+
!!send(field_name)
|
44
|
+
end
|
45
|
+
# Writers
|
46
|
+
writers.each do |writer_name|
|
47
|
+
define_method "#{writer_name}=" do |value|
|
48
|
+
write_attribute(field_name, value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
# Dirty attribute helpers.
|
53
|
+
define_attribute_methods [field_name]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_xml(xml, soap, value, options={})
|
58
|
+
qualifier = soap.namespace_by_uri(namespace)
|
59
|
+
nil_strategy = options[:nil_strategy] || :omit
|
60
|
+
# The extra qualifiers attribute needs to be passed in
|
61
|
+
# in case the field is another complexType that needs
|
62
|
+
# to be namespaced.
|
63
|
+
if !value.nil? || nil_strategy == :whitespace
|
64
|
+
xml.tag!(qualifier, zuora_name.to_sym, value.to_s)
|
65
|
+
elsif nil_strategy == :fields_to_null
|
66
|
+
xml.tag!(qualifier, :fieldsToNull, zuora_name.to_sym)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def clear_changed_attributes(value)
|
71
|
+
# If the value of this field has attribute changes to clear,
|
72
|
+
# override this function.
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class ObjectField < Field
|
3
|
+
|
4
|
+
# A field that is itself another Zuora complex type.
|
5
|
+
# Hashes will automatically be converted to an instance of the given class.
|
6
|
+
|
7
|
+
attr_accessor :class_name
|
8
|
+
|
9
|
+
def initialize(name, namespace, class_name, options={})
|
10
|
+
@class_name = class_name
|
11
|
+
super(name, namespace, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def type_cast(value)
|
15
|
+
if value.is_a?(Hash)
|
16
|
+
value = class_name.constantize.new(value)
|
17
|
+
end
|
18
|
+
value
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_xml(xml, soap, value, options={})
|
22
|
+
# For complex types, simply omit it if it's nil.
|
23
|
+
value.build_xml(xml, soap, :namespace => namespace, :element_name => zuora_name) if value
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear_changed_attributes(value)
|
27
|
+
value.clear_changed_attributes if value
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
module Generate
|
3
|
+
|
4
|
+
# This is meant to be included onto an Invoice class.
|
5
|
+
# Returns true/false on success.
|
6
|
+
# Result hash is stored in #result.
|
7
|
+
# If success, the id will be set in the object.
|
8
|
+
# If failure, errors will be present on object.
|
9
|
+
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
include Base
|
14
|
+
attr_accessor :result
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
self.result = self.class.connection.request(:generate) do |soap|
|
19
|
+
soap.body do |xml|
|
20
|
+
build_xml(xml, soap,
|
21
|
+
:namespace => soap.namespace,
|
22
|
+
:element_name => :zObjects,
|
23
|
+
:force_type => true)
|
24
|
+
end
|
25
|
+
end[:generate_response][:result]
|
26
|
+
|
27
|
+
if result[:success]
|
28
|
+
self.id = result[:id]
|
29
|
+
self.status = 'Draft'
|
30
|
+
clear_changed_attributes
|
31
|
+
true
|
32
|
+
else
|
33
|
+
add_zuora_errors(result[:errors])
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate!
|
39
|
+
raise "Could not generate: #{errors.full_messages.join ', '}" unless generate
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
class Generator
|
3
|
+
|
4
|
+
attr_reader :document, :classes
|
5
|
+
|
6
|
+
def initialize(document, options={})
|
7
|
+
# document is a parsed wsdl document.
|
8
|
+
@document = document
|
9
|
+
@classes = []
|
10
|
+
@class_nesting = options[:inside] || ActiveZuora
|
11
|
+
@class_nesting.const_set("CollectionProxy", CollectionProxy) unless @class_nesting.constants.include?(:CollectionProxy)
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_classes
|
15
|
+
|
16
|
+
# Defines the classes based on the wsdl document.
|
17
|
+
# Assumes the following namespaces in the wsdl.
|
18
|
+
# xmlns="http://schemas.xmlsoap.org/wsdl/"
|
19
|
+
# xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
|
20
|
+
# xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
21
|
+
# xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
22
|
+
# xmlns:zns="http://api.zuora.com/"
|
23
|
+
# xmlns:ons="http://object.api.zuora.com/"
|
24
|
+
# xmlns:fns="http://fault.api.zuora.com/"
|
25
|
+
@document.xpath('.//xs:schema[@targetNamespace]').each do |schema|
|
26
|
+
namespace = schema.attribute("targetNamespace").value
|
27
|
+
|
28
|
+
schema.xpath('.//xs:complexType[@name]').each do |complex_type|
|
29
|
+
class_name = complex_type.attribute("name").value
|
30
|
+
# Skip the zObject base class, we define our own.
|
31
|
+
next if class_name == "zObject"
|
32
|
+
|
33
|
+
class_name[0] = class_name[0].upcase
|
34
|
+
zuora_class = Class.new
|
35
|
+
@class_nesting.const_set(class_name, zuora_class)
|
36
|
+
@classes << zuora_class
|
37
|
+
|
38
|
+
# Include the Base module for adding fields.
|
39
|
+
zuora_class.send :include, Base
|
40
|
+
zuora_class.namespace = namespace
|
41
|
+
|
42
|
+
# If it's a zObject, include that module as well.
|
43
|
+
if complex_type.xpath(".//xs:extension[@base='ons:zObject']").any?
|
44
|
+
zuora_class.send :include, ZObject
|
45
|
+
end
|
46
|
+
|
47
|
+
# Define the fields
|
48
|
+
complex_type.xpath('.//xs:element[@name][@type]').each do |element|
|
49
|
+
# attributes: name, type, nillable, minoccurs, maxoccurs
|
50
|
+
zuora_name = element.attribute("name").value
|
51
|
+
field_name = zuora_name.underscore
|
52
|
+
field_type = element.attribute("type").value
|
53
|
+
is_array = element_is_an_array?(element)
|
54
|
+
|
55
|
+
case field_type
|
56
|
+
when "string", "xs:string", "zns:ID", "xs:base64Binary"
|
57
|
+
zuora_class.field field_name, :string,
|
58
|
+
:zuora_name => zuora_name, :array => is_array
|
59
|
+
when "boolean", "xs:boolean"
|
60
|
+
zuora_class.field field_name, :boolean,
|
61
|
+
:zuora_name => zuora_name, :array => is_array
|
62
|
+
when "int", "short", "long", "xs:int"
|
63
|
+
zuora_class.field field_name, :integer,
|
64
|
+
:zuora_name => zuora_name, :array => is_array
|
65
|
+
when "decimal"
|
66
|
+
zuora_class.field field_name, :decimal,
|
67
|
+
:zuora_name => zuora_name, :array => is_array
|
68
|
+
when "date"
|
69
|
+
zuora_class.field field_name, :date,
|
70
|
+
:zuora_name => zuora_name, :array => is_array
|
71
|
+
when "dateTime"
|
72
|
+
zuora_class.field field_name, :datetime,
|
73
|
+
:zuora_name => zuora_name, :array => is_array
|
74
|
+
when /\A(zns:|ons:)/
|
75
|
+
zuora_class.field field_name, :object,
|
76
|
+
:zuora_name => zuora_name, :array => is_array,
|
77
|
+
:class_name => zuora_class.nested_class_name(field_type.split(':').last)
|
78
|
+
else
|
79
|
+
puts "Unknown field type: #{field_type}"
|
80
|
+
end
|
81
|
+
end # each element
|
82
|
+
|
83
|
+
end # each complexType
|
84
|
+
end # each schema
|
85
|
+
|
86
|
+
add_obvious_associations
|
87
|
+
add_extra_customizations
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def add_obvious_associations
|
93
|
+
# When a zuora class has a field called InvoiceId, it's a safe
|
94
|
+
# assuption that it references the an Invoice.
|
95
|
+
# Build those associations automatically.
|
96
|
+
@classes.each do |zuora_class|
|
97
|
+
zuora_class.fields.each do |field|
|
98
|
+
# If it looks like an Id field and the name
|
99
|
+
# matches a generated ZObject class
|
100
|
+
if match = field.zuora_name.match(/\A(.+?)Id\Z/)
|
101
|
+
if zobject_class = zobject_class_with_name(match[1])
|
102
|
+
# Add a belongs to relationship.
|
103
|
+
zuora_class.belongs_to zobject_class.zuora_object_name.underscore
|
104
|
+
# If the current class is also a ZObject, add a has_many
|
105
|
+
# to the referenced class.
|
106
|
+
if zuora_class < ZObject
|
107
|
+
zobject_class.has_many zuora_class.zuora_object_name.underscore.pluralize
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_extra_customizations
|
116
|
+
# We can't know everything from the wsdl, like which fields are
|
117
|
+
# usable in queries. This function does some final customizations
|
118
|
+
# based on the existing Zuora documentation.
|
119
|
+
# Also, it's possible classes customized here weren't defined
|
120
|
+
# in your wsdl, so it will only customize them if they are defined.
|
121
|
+
|
122
|
+
nesting = @class_nesting
|
123
|
+
|
124
|
+
customize 'Account' do
|
125
|
+
belongs_to :bill_to, :class_name => nested_class_name('Contact') if field? :bill_to_id
|
126
|
+
belongs_to :default_payment_method, :class_name => nested_class_name('PaymentMethod') if field? :default_payment_method_id
|
127
|
+
if field? :parent_id
|
128
|
+
belongs_to :parent, :class_name => nested_class_name('Account')
|
129
|
+
has_many :children, :class_name => nested_class_name('Account'), :foreign_key => :parent_id, :inverse_of => :parent
|
130
|
+
end
|
131
|
+
belongs_to :sold_to, :class_name => nested_class_name('Contact') if field? :sold_to_id
|
132
|
+
validates :currency, :presence => true if field? :currency
|
133
|
+
validates :name, :presence => true if field? :name
|
134
|
+
validates :status, :presence => true if field? :status
|
135
|
+
end
|
136
|
+
|
137
|
+
customize 'Amendment' do
|
138
|
+
exclude_from_queries :rate_plan_data,
|
139
|
+
:destination_account_id, :destination_invoice_owner_id
|
140
|
+
end
|
141
|
+
|
142
|
+
customize 'AmendRequest' do
|
143
|
+
include Amend
|
144
|
+
end
|
145
|
+
|
146
|
+
customize 'Import' do
|
147
|
+
exclude_from_queries :file_content
|
148
|
+
end
|
149
|
+
|
150
|
+
customize 'Invoice' do
|
151
|
+
include Generate
|
152
|
+
include LazyAttr
|
153
|
+
# The body field can only be accessed for a single invoice at a time, so
|
154
|
+
# exclude it here to not break collections of invoices. The contents of
|
155
|
+
# the body field will be lazy loaded in when needed.
|
156
|
+
exclude_from_queries :regenerate_invoice_pdf, :body, :bill_run_id
|
157
|
+
lazy_load :body
|
158
|
+
end
|
159
|
+
|
160
|
+
customize 'InvoiceItem' do
|
161
|
+
exclude_from_queries :product_rate_plan_charge_id
|
162
|
+
end
|
163
|
+
|
164
|
+
customize 'BillingPreviewRequest' do
|
165
|
+
include BillingPreview
|
166
|
+
end
|
167
|
+
|
168
|
+
customize 'InvoiceItemAdjustment' do
|
169
|
+
exclude_from_queries :customer_name, :customer_number
|
170
|
+
end
|
171
|
+
|
172
|
+
customize 'Payment' do
|
173
|
+
exclude_from_queries :applied_invoice_amount,
|
174
|
+
:gateway_option_data, :invoice_id, :invoice_number, :invoice_payment_data
|
175
|
+
end
|
176
|
+
|
177
|
+
customize 'PaymentMethod' do
|
178
|
+
exclude_from_queries :ach_account_number, :bank_transfer_account_number,
|
179
|
+
:credit_card_number, :credit_card_security_code, :gateway_option_data,
|
180
|
+
:second_token_id, :skip_validation, :token_id
|
181
|
+
end
|
182
|
+
|
183
|
+
customize 'ProductRatePlan' do
|
184
|
+
include LazyAttr
|
185
|
+
exclude_from_queries :active_currencies
|
186
|
+
lazy_load :active_currencies
|
187
|
+
end
|
188
|
+
|
189
|
+
customize 'ProductRatePlanCharge' do
|
190
|
+
exclude_from_queries :product_rate_plan_charge_tier_data, :revenue_recognition_rule_name, :deferred_revenue_account, :recognized_revenue_account, :product_discount_apply_detail_data
|
191
|
+
end
|
192
|
+
|
193
|
+
customize 'Usage' do
|
194
|
+
exclude_from_queries :ancestor_account_id, :invoice_id, :invoice_number
|
195
|
+
end
|
196
|
+
|
197
|
+
customize 'RatePlanCharge' do
|
198
|
+
include LazyAttr
|
199
|
+
exclude_from_queries :overage_price, :included_units,
|
200
|
+
:discount_amount, :discount_percentage, :rollover_balance, :price, :revenue_recognition_rule_name
|
201
|
+
lazy_load :price
|
202
|
+
end
|
203
|
+
|
204
|
+
customize 'Refund' do
|
205
|
+
exclude_from_queries :gateway_option_data, :payment_id
|
206
|
+
end
|
207
|
+
|
208
|
+
customize 'Subscription' do
|
209
|
+
exclude_from_queries :ancestor_account_id
|
210
|
+
belongs_to :creator_account, :class_name => nested_class_name('Account') if field? :creator_account_id
|
211
|
+
belongs_to :creator_invoice_owner, :class_name => nested_class_name('Account') if field? :creator_invoice_owner_id
|
212
|
+
belongs_to :invoice_owner, :class_name => nested_class_name('Account') if field? :invoice_owner_id
|
213
|
+
belongs_to :original, :class_name => name if field? :original_id
|
214
|
+
belongs_to :original_subscription, :class_name => name if field? :original_subscription_id
|
215
|
+
belongs_to :previous_subscription, :class_name => name if field? :previous_subscription_id
|
216
|
+
end
|
217
|
+
|
218
|
+
customize 'SubscribeRequest' do
|
219
|
+
include Subscribe
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def customize(zuora_class_name, &block)
|
224
|
+
if @class_nesting.const_defined?(zuora_class_name)
|
225
|
+
@class_nesting.const_get(zuora_class_name).instance_eval(&block)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
def element_is_an_array?(element)
|
231
|
+
attribute_is_more_than_one?(element.attribute("minOccurs")) ||
|
232
|
+
attribute_is_more_than_one?(element.attribute("maxOccurs"))
|
233
|
+
end
|
234
|
+
|
235
|
+
def attribute_is_more_than_one?(attribute)
|
236
|
+
attribute && ( attribute.value == "unbounded" || attribute.value.to_i > 1 )
|
237
|
+
end
|
238
|
+
|
239
|
+
def zobject_class_with_name(name)
|
240
|
+
@classes.find { |zuora_class| zuora_class.zuora_object_name == name && zuora_class < ZObject }
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
end
|