diff --git a/.travis.yml b/.travis.yml index cbb389a..ec0b53d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,24 @@ language: ruby before_script: "bundle exec rake appraisal:install" script: "bundle exec rake appraisal spec" rvm: - - 2.1.2 - - 2.1.3 - - 2.1.4 - - 2.1.5 + - ree + - 1.8.7 + - 1.9.2 + - 1.9.3 + - rbx-18mode + - rbx-19mode + - jruby-18mode + - jruby-19mode + - 2.0.0 + - 2.1.7 + - 2.2.3 +matrix: + allow_failures: + - rvm: rbx-18mode + - rvm: rbx-19mode + - rvm: jruby-18mode + - rvm: jruby-19mode +notifications: + recipients: + - josh.martin@wildfireapp.com + - wael.nasreddine@wildfireapp.com diff --git a/Gemfile b/Gemfile index 173209a..fa75df1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,3 @@ source 'https://rubygems.org' -gem 'pry' - -gem 'wasabi', :git => 'git://github.com/skiz/wasabi.git' - gemspec - diff --git a/LICENSE b/LICENSE index 1eafde8..ef51da2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,20 +1,202 @@ -Copyright (c) 2012 Wildfire Interactive, Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index 9708a23..3e50980 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Zuora [![Build Status](https://secure.travis-ci.org/backupify/zuora.png?branch=master)](http://travis-ci.org/backupify/zuora) +# Zuora [![Build Status](https://secure.travis-ci.org/wildfireapp/zuora.png?branch=master)](http://travis-ci.org/wildfireapp/zuora) [![Gemnasium](https://gemnasium.com/wildfireapp/zuora.png)](https://gemnasium.com/wildfireapp/zuora) This library allows you to interact with [Zuora](http://www.zuora.com) billing platform directly using familiar [ActiveModel](https://github.com/rails/rails/tree/master/activemodel) based objects. @@ -13,33 +13,40 @@ All additional requirements for development should be referenced in the provided ## Installation - git clone git@github.com:wildfireapp/zuora.git + git clone git@github.com:zuorasc/zuora.git ## Getting Started $ bundle install $ bundle exec irb -rzuora - Zuora.configure(:username => 'USER', :password => 'PASS') +``` + Zuora.configure(:username => 'USER', :password => 'PASS', sandbox: true, log: true) + + account = Zuora::Objects::Account.new + => #nil, "currency"=>nil, + "batch"=>nil, "bill_cycle_day"=>nil, "status"=>nil, "payment_term"=>nil}, @auto_pay=false, @currency="USD", + @batch="Batch1", @bill_cycle_day=1, @status="Draft", @payment_term="Due Upon Receipt"> + + account.name = "Test" + => "Test" + + account.create + => true + + created_account = Zuora::Objects::Account.find(account.id) + => #, @bcd_setting_option="ManualSet", + @created_by_id="2c92c0f83b02a9dc013b0a7e26a03d00", @created_date=Wed, 16 Jan 2013 10:25:24 -0800, + @invoice_delivery_prefs_email=false, @invoice_delivery_prefs_print=false, @name="Test", + @updated_by_id="2c92c0f83b02a9dc013b0a7e26a03d00", @updated_date=Wed, 16 Jan 2013 10:25:24 -0800> +``` - account = Zuora::Objects::Account.create(:account_number => '12345') - # => 12345, :id => 'abc123'> - Zuora::Objects::Account.find('abc123') - # => 12345, :id => 'abc123'> - account.destroy - # => true - -## Documentation - You can generate up to date documentation with the provided a rake task. - - $ rake doc - $ open doc/index.html - -## Advanced Usage - Review the generated documentation for usage patterns and examples of using specific zObjects. ## Test Suite - This library comes with a full test suite, which can be run using the stanard rake utility. + This library comes with a full test suite, which can be ran using the standard rake utility. $ rake spec @@ -55,12 +62,45 @@ All additional requirements for development should be referenced in the provided ## Support & Maintenance This library currently supports Zuora's SOAP API version 38. + If you would like to test out the **EXPERIMENTAL** API version 51 support, see + the a51 branch and please file bugs and pull requests against it. + ## Contributors - * Josh Martin - * Alex Reyes - * Wael Nasreddine + * Josh Martin + * Alex Reyes + * Wael Nasreddine + * [mdemin914](http://github.com/mdemin914) + * [jmonline](http://github.com/jmonline) ## Credits * [Wildfire Ineractive](http://www.wildfireapp.com) for facilitating the development and maintenance of the project. * [Zuora](http://www.zuora.com) for providing us with the opportunity to share this library with the community. +#Legal Notice + Copyright (c) 2013 Zuora, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to use copy, + modify, merge, publish the Software and to distribute, and sublicense copies of + the Software, provided no fee is charged for the Software. In addition the + rights specified above are conditioned upon the following: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + Zuora, Inc. or any other trademarks of Zuora, Inc. may not be used to endorse + or promote products derived from this Software without specific prior written + permission from Zuora, Inc. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + ZUORA, INC. BE LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + IN THE EVENT YOU ARE AN EXISTING ZUORA CUSTOMER, USE OF THIS SOFTWARE IS GOVERNED + BY THIS AGREEMENT AND NOT YOUR MASTER SUBSCRIPTION AGREEMENT WITH ZUORA. diff --git a/lib/zuora/api.rb b/lib/zuora/api.rb index de5f92a..f1f2587 100644 --- a/lib/zuora/api.rb +++ b/lib/zuora/api.rb @@ -11,21 +11,18 @@ module Zuora # @return [Config] def self.configure(opts={}) Api.instance.config = Config.new(opts) - HTTPI.logger = opts[:logger] - HTTPI.log = opts[:logger] ? true : false - Savon.configure do |savon| - savon.logger = opts[:logger] - savon.log = opts[:logger] ? true : false - end - if Api.instance.config.sandbox Api.instance.sandbox! + elsif Api.instance.config.services + Api.instance.set_endpoint Api.instance.config.custom_url end end class Api include Singleton + I18n.enforce_available_locales = false + # @return [Savon::Client] def client @client ||= make_client @@ -37,8 +34,17 @@ def client # @return [Zuora::Config] attr_accessor :config - PRODUCTION_WSDL = File.expand_path('../../../wsdl/production/zuora.a.38.0.wsdl', __FILE__) - SANDBOX_WSDL = File.expand_path('../../../wsdl/sandbox/zuora.a.38.0.wsdl', __FILE__) + # 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 # Is this an authenticated session? # @return [Boolean] @@ -46,37 +52,45 @@ def authenticated? self.session.try(:active?) end - # Change client to sandbox url + # Change client to use sandbox url def sandbox! @client = nil - self.class.instance.client.wsdl.document = SANDBOX_WSDL + 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] - def last_request - client.http.body - end + attr_reader :last_request # 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 # @raise [Zuora::Fault] - def request(method, xml_body=nil, &block) + def request(method, options={}, &block) authenticate! unless authenticated? - response = client.request(method) do - soap.header = {'env:SessionHeader' => {'ins0:Session' => self.session.try(:key) }} - if block_given? - soap.body{|xml| yield xml } - else - soap.body = xml_body - end + if block_given? + xml = Builder::XmlMarkup.new + yield xml + options[:message] = xml.target! end - rescue Savon::SOAP::Fault, IOError => e + client.call(method, options) + rescue Savon::SOAPFault, IOError => e raise Zuora::Fault.new(:message => e.message) end @@ -88,30 +102,28 @@ def request(method, xml_body=nil, &block) # Upon failure a Zoura::Fault will be raised. # @raise [Zuora::Fault] def authenticate! - response = client.request(:login) do - ns = Zuora::Api.instance.client.soap.namespace_by_uri('http://api.zuora.com/') - soap.body = "<#{ns}:username>#{Zuora::Api.instance.config.username}<#{ns}:password>#{Zuora::Api.instance.config.password}" + response = client.call(:login) do + message username: Zuora::Api.instance.config.username, + password: Zuora::Api.instance.config.password end self.session = Zuora::Session.generate(response.to_hash) - rescue Savon::SOAP::Fault => e + client.globals.soap_header({'env:SessionHeader' => {'ins0:Session' => self.session.try(:key) }}) + rescue Savon::SOAPFault => e raise Zuora::Fault.new(:message => e.message) end private def initialize - Savon.configure do |savon| - savon.soap_version = 2 - end + @config = Config.new end def make_client - Savon::Client.new do - wsdl.document = defined?(ZUORA_WSDL) ? ZUORA_WSDL : PRODUCTION_WSDL - http.auth.ssl.verify_mode = :none - end + Savon.client(wsdl: WSDL, soap_version: SOAP_VERSION, log: config.log || true, ssl_verify_mode: :none) end end -end + # Support request tracking via notify + Savon.observers << Api.instance +end diff --git a/lib/zuora/attributes.rb b/lib/zuora/attributes.rb index 076d4d6..606def0 100644 --- a/lib/zuora/attributes.rb +++ b/lib/zuora/attributes.rb @@ -51,7 +51,8 @@ def #{scope}_with_complex @#{scope} = #{scope}_without_complex end end - alias_method_chain :#{scope}, :complex + alias_method :#{scope}_without_complex, :#{scope} + alias_method :#{scope}, :#{scope}_with_complex EVAL end end @@ -135,7 +136,7 @@ def remote_name def inherited(subclass) super xpath = "//xs:complexType[@name='#{subclass.remote_name}']//xs:sequence/xs:element" - document = Zuora::Api.instance.client.wsdl.parser.instance_variable_get('@document') + document = Zuora::Api.instance.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'].value.underscore.to_sym }) << :id subclass.send(:class_variable_set, :@@wsdl_attributes, wsdl_attrs) diff --git a/lib/zuora/core_ext/string.rb b/lib/zuora/core_ext/string.rb index 54a1109..5c6106a 100644 --- a/lib/zuora/core_ext/string.rb +++ b/lib/zuora/core_ext/string.rb @@ -7,11 +7,16 @@ def base_name end unless method_defined?(:base_name) def zuora_camelize - self.include?('__c') ? self.chomp('__c').camelize + '__c' : self.camelize - end + if match(/__c$/) + self.gsub("__c","").zuora_camelize + "__c" + else + camelize + end + end unless method_defined?(:zuora_camelize) end end end String.send :include, Zuora::CoreExt::String + diff --git a/lib/zuora/objects/account.rb b/lib/zuora/objects/account.rb index ac27915..f24bcb1 100644 --- a/lib/zuora/objects/account.rb +++ b/lib/zuora/objects/account.rb @@ -1,6 +1,5 @@ module Zuora::Objects class Account < Base - include ActiveModel has_many :contacts has_many :payment_methods has_many :subscriptions @@ -31,4 +30,3 @@ class Account < Base end end end - diff --git a/lib/zuora/objects/amendment.rb b/lib/zuora/objects/amendment.rb index a012351..a1d2477 100644 --- a/lib/zuora/objects/amendment.rb +++ b/lib/zuora/objects/amendment.rb @@ -6,14 +6,14 @@ class Amendment < Base 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_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_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"] @@ -21,8 +21,6 @@ class Amendment < Base 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) } - store_accessors :amend_options - attr_accessor :amendment_ids attr_accessor :invoice_id attr_accessor :payment_transaction_number @@ -51,12 +49,5 @@ def apply_response(response_hash, type) return false end end - - # Implementation adapted from jmoline/zuora 54cdde65a5de761162cbc6bbdd930082349582fb - def generate_amend_options(builder) - amend_options.each do |k,v| - builder.__send__(zns, k.to_s.zuora_camelize.to_sym, v) - end - end end end diff --git a/lib/zuora/objects/base.rb b/lib/zuora/objects/base.rb index dfb52a8..51c37a6 100644 --- a/lib/zuora/objects/base.rb +++ b/lib/zuora/objects/base.rb @@ -55,7 +55,7 @@ def self.unselectable_attributes end def self.namespace(uri) - Zuora::Api.instance.client.soap.namespace_by_uri(uri) + Zuora::Api.instance.client.operation(:query).build.send(:namespace_by_uri, uri) end def self.zns @@ -74,36 +74,37 @@ def ons self.class.ons 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 = (attributes - unselectable_attributes).map(&:to_s).map(&:zuora_camelize) - where_clause = where - if where.is_a?(Hash) - parts = [] - - where.each do |k, v| - attribute = k.to_s.zuora_camelize - - if v.kind_of?(Array) - disjunction = v.join("' or #{attribute} = '") - parts << "#{attribute} = '#{disjunction}'" - else - parts << "#{attribute} = '#{v}'" - end - end - - where_clause = parts.sort.join(' and ') + # FIXME: improper inject usage. + where = where.inject([]){|t,v| t << "#{v[0].to_s.zuora_camelize} = '#{v[1]}'"}.sort.join(' and ') end + sql = "select #{keys.join(', ')} from #{remote_name} where #{where}" - sql = "select #{keys.join(', ')} from #{remote_name} where #{where_clause}" result = self.connector.query(sql) 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? diff --git a/lib/zuora/objects/credit_balance_adjustment.rb b/lib/zuora/objects/credit_balance_adjustment.rb index 6cbc718..7bd1e34 100644 --- a/lib/zuora/objects/credit_balance_adjustment.rb +++ b/lib/zuora/objects/credit_balance_adjustment.rb @@ -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 diff --git a/lib/zuora/objects/invoice.rb b/lib/zuora/objects/invoice.rb index d7a4018..4d3a834 100644 --- a/lib/zuora/objects/invoice.rb +++ b/lib/zuora/objects/invoice.rb @@ -15,20 +15,20 @@ class Invoice < Base validates_numericality_of :amount validates_numericality_of :balance, :allow_nil => true validates_length_of :comments, :maximum => 255 - validates_datetime_of :due_date - validates_datetime_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] validates_length_of :invoice_number, :maximum => 255 # String - validates_datetime_of :last_email_sent_date, :allow_nil => true + # validates_datetime_of :last_email_sent_date, :allow_nil => true validates_numericality_of :payment_amount, :allow_nil => true - validates_datetime_of :posted_date, :allow_nil => true + # 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_datetime_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 + # validates_datetime_of :updated_date define_attributes do read_only( diff --git a/lib/zuora/objects/invoice_adjustment.rb b/lib/zuora/objects/invoice_adjustment.rb index 3ae3e73..858dcc0 100644 --- a/lib/zuora/objects/invoice_adjustment.rb +++ b/lib/zuora/objects/invoice_adjustment.rb @@ -7,14 +7,14 @@ class InvoiceAdjustment < Base validates_presence_of :amount, :type validates_length_of :accounting_code, :maximum => 100 - validates_datetime_of :adjustment_date, :allow_nil => true + # validates_datetime_of :adjustment_date, :allow_nil => true validates_length_of :adjustment_number, :maximum => 50 validates_numericality_of :amount validates_length_of :cancelled_by_id, :maximum => 32 - validates_datetime_of :cancelled_on, :allow_nil => true + # validates_datetime_of :cancelled_on, :allow_nil => true validates_length_of :comments, :maximum => 255 validates_length_of :created_by_id, :maximum => 32 - validates_datetime_of :created_date, :allow_nil => true + # validates_datetime_of :created_date, :allow_nil => true validates_length_of :customer_name, :maximum => 50, :allow_nil => true validates_length_of :customer_number, :maximum => 70, :allow_nil => true validates_presence_of :invoice_id, :if => Proc.new { |ia| ia.invoice_number.nil? } @@ -23,7 +23,7 @@ class InvoiceAdjustment < Base validates_inclusion_of :transferred_to_accounting, :in => %w(Processing Yes Error Ignore), :allow_nil => true validates_inclusion_of :type, :in => %w(Credit Charge) validates_length_of :updated_by_id, :maximum => 32, :allow_nil => true - validates_datetime_of :updated_date + # validates_datetime_of :updated_date define_attributes do read_only( diff --git a/lib/zuora/objects/invoice_item.rb b/lib/zuora/objects/invoice_item.rb index 4a6187f..204aa17 100644 --- a/lib/zuora/objects/invoice_item.rb +++ b/lib/zuora/objects/invoice_item.rb @@ -10,7 +10,7 @@ class InvoiceItem < Base validates_length_of :accounting_code, :maximum => 255, :allow_nil => true validates_numericality_of :charge_amount - validates_datetime_of :charge_date + # validates_datetime_of :charge_date validates_length_of :charge_name, :maximum => 50, :allow_nil => true validates_length_of :created_by_id, :maximum => 32, :allow_nil => true validates_inclusion_of :processing_type, :in => [0,1,2,3], :allow_nil => true @@ -18,9 +18,9 @@ class InvoiceItem < Base validates_length_of :product_name, :maximum => 255 validates_numericality_of :quantity, :allow_nil => true validates_length_of :rev_rec_code, :maximum => 70 - validates_datetime_of :rev_rec_start_date, :allow_nil => true - validates_datetime_of :service_end_date, :allow_nil => true - validates_datetime_of :service_start_date + # validates_datetime_of :rev_rec_start_date, :allow_nil => true + # validates_datetime_of :service_end_date, :allow_nil => true + # validates_datetime_of :service_start_date validates_length_of :sku, :maximum => 255 validates_numericality_of :unit_price validates_length_of :uom, :maximum => 255 @@ -30,6 +30,7 @@ class InvoiceItem < Base read_only :charge_description, :charge_name, :charge_number, :created_by_id, :created_date, :invoice_id, :product_description, :quantity, :subscription_number, :updated_by_id, :updated_date + deferred_attributes :product_rate_plan_charge_id end end end diff --git a/lib/zuora/objects/invoice_item_adjustment.rb b/lib/zuora/objects/invoice_item_adjustment.rb index b08b40e..fdff9da 100644 --- a/lib/zuora/objects/invoice_item_adjustment.rb +++ b/lib/zuora/objects/invoice_item_adjustment.rb @@ -6,14 +6,14 @@ class InvoiceItemAdjustment < Base validates_presence_of :amount, :type validates_length_of :accounting_code, :maximum => 100 - validates_datetime_of :adjustment_date, :allow_nil => true + # validates_datetime_of :adjustment_date, :allow_nil => true validates_length_of :adjustment_number, :maximum => 50 validates_numericality_of :amount validates_length_of :cancelled_by_id, :maximum => 32 - validates_datetime_of :cancelled_on, :allow_nil => true + # validates_datetime_of :cancelled_on, :allow_nil => true validates_length_of :comments, :maximum => 255 validates_length_of :created_by_id, :maximum => 32 - validates_datetime_of :created_date, :allow_nil => true + # validates_datetime_of :created_date, :allow_nil => true validates_length_of :customer_name, :maximum => 50, :allow_nil => true validates_length_of :customer_number, :maximum => 70, :allow_nil => true validates_numericality_of :impact_amount @@ -22,15 +22,15 @@ class InvoiceItemAdjustment < Base validates_presence_of :invoice_number, :if => Proc.new { |ia| ia.invoice_id.nil? } validates_length_of :invoice_number, :maximum => 255 validates_length_of :reference_id, :maximum => 60, :allow_nil => true - validates_datetime_of :service_end_date - validates_datetime_of :service_start_date + # validates_datetime_of :service_end_date + # validates_datetime_of :service_start_date validates_length_of :source_id, :maximum => 32, :allow_nil => true validates_inclusion_of :source_type, :in => %w(InvoiceDetail Tax) validates_inclusion_of :status, :in => %w(Canceled Processed) validates_inclusion_of :transferred_to_accounting, :in => %w(Processing Yes Error Ignore), :allow_nil => true validates_inclusion_of :type, :in => %w(Credit Charge) validates_length_of :updated_by_id, :maximum => 32, :allow_nil => true - validates_datetime_of :updated_date + # validates_datetime_of :updated_date define_attributes do read_only( diff --git a/lib/zuora/objects/invoice_payment.rb b/lib/zuora/objects/invoice_payment.rb index 63a0055..040b52c 100644 --- a/lib/zuora/objects/invoice_payment.rb +++ b/lib/zuora/objects/invoice_payment.rb @@ -1,18 +1,18 @@ -#module Zuora::Objects - #class InvoicePayment < Base - #belongs_to :invoice - #belongs_to :payment +module Zuora::Objects + class InvoicePayment < Base + belongs_to :invoice + belongs_to :payment - #validates_presence_of :amount, :invoice_id, :payment_id - #validates_numericality_of :amount - #validates_length_of :created_by_id, :maximum => 32 - #validates_datetime_of :created_date, :allow_nil => true - #validates_numericality_of :refund_amount - #validates_length_of :updated_by_id, :maximum => 32 - #validates_datetime_of :update_date, :allow_nil => true + validates_presence_of :amount, :invoice_id, :payment_id + validates_numericality_of :amount + validates_length_of :created_by_id, :maximum => 32 + # validates_datetime_of :created_date, :allow_nil => true + validates_numericality_of :refund_amount + validates_length_of :updated_by_id, :maximum => 32 + # validates_datetime_of :update_date, :allow_nil => true - #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 diff --git a/lib/zuora/objects/payment.rb b/lib/zuora/objects/payment.rb index 90beeda..5f3faa7 100644 --- a/lib/zuora/objects/payment.rb +++ b/lib/zuora/objects/payment.rb @@ -1,41 +1,41 @@ -#module Zuora::Objects - #class Payment < Base - #belongs_to :account - #belongs_to :invoice +module Zuora::Objects + class Payment < Base + belongs_to :account + belongs_to :invoice - #validates_presence_of :account_id, :amount, :effective_date, :gateway_state, - #:payment_method_id, :status, :type + validates_presence_of :account_id, :amount, :effective_date, :gateway_state, + :payment_method_id, :status, :type - #validates_length_of :accounting_code, :maximum => 100, :allow_nil => true - #validates_numericality_of :amount - #validates_numericality_of :applied_credit_balance_amount - #validates_numericality_of :applied_invoice_amount - #validates_length_of :auth_transaction_id, :maximum => 50, :allow_nil => true - #validates_length_of :bank_identification_number, :maximum => 6, :allow_nil => true - #validates_date_of :cancelled_on, :allow_nil => true - #validates_length_of :comment, :maximum => 255, :allow_nil => true - #validates_length_of :created_by_id, :maximum => 32, :allow_nil => true - #validates_datetime_of :effective_date - #validates_length_of :gateway_order_id, :maximum => 70, :allow_nil => true - #validates_inclusion_of :gateway_state, :in => %w(NotSubmitted Submitted Settled MarkedForSubmission) - #validates_datetime_of :marked_for_submission_on, :allow_nil => true - #validates_length_of :payment_number, :maximum => 32, :allow_nil => true - #validates_length_of :reference_id, :maximum => 30, :allow_nil => true - #validates_numericality_of :refund_amount, :allow_nil => true - #validates_length_of :second_payment_reference_id, :maximum => 60, :allow_nil => true - #validates_date_of :settled_on, :allow_nil => true - #validates_length_of :soft_descriptor, :maximum => 35, :allow_nil => true - #validates_length_of :soft_descriptor_phone, :maximum => 20, :allow_nil => true - #validates_inclusion_of :status, :in => %w(Canceled Draft Error Posted Processing Processed Voided) - #validates_date_of :submitted_on, :allow_nil => true - #validates_inclusion_of :transferred_to_accouning, :allow_nil => true, :in => %w(Processing Yes Error Ignore) - #validates_inclusion_of :type, :in => %w(External Electronic) - #validates_length_of :updated_by_id, :maximum => 32 - #validates_datetime_of :updated_date + validates_length_of :accounting_code, :maximum => 100, :allow_nil => true + validates_numericality_of :amount + validates_numericality_of :applied_credit_balance_amount + validates_numericality_of :applied_invoice_amount + validates_length_of :auth_transaction_id, :maximum => 50, :allow_nil => true + validates_length_of :bank_identification_number, :maximum => 6, :allow_nil => true + # validates_date_of :cancelled_on, :allow_nil => true + validates_length_of :comment, :maximum => 255, :allow_nil => true + validates_length_of :created_by_id, :maximum => 32, :allow_nil => true + # validates_datetime_of :effective_date + validates_length_of :gateway_order_id, :maximum => 70, :allow_nil => true + validates_inclusion_of :gateway_state, :in => %w(NotSubmitted Submitted Settled MarkedForSubmission) + # validates_datetime_of :marked_for_submission_on, :allow_nil => true + validates_length_of :payment_number, :maximum => 32, :allow_nil => true + validates_length_of :reference_id, :maximum => 30, :allow_nil => true + validates_numericality_of :refund_amount, :allow_nil => true + validates_length_of :second_payment_reference_id, :maximum => 60, :allow_nil => true + # validates_date_of :settled_on, :allow_nil => true + validates_length_of :soft_descriptor, :maximum => 35, :allow_nil => true + validates_length_of :soft_descriptor_phone, :maximum => 20, :allow_nil => true + validates_inclusion_of :status, :in => %w(Canceled Draft Error Posted Processing Processed Voided) + # validates_date_of :submitted_on, :allow_nil => true + validates_inclusion_of :transferred_to_accouning, :allow_nil => true, :in => %w(Processing Yes Error Ignore) + validates_inclusion_of :type, :in => %w(External Electronic) + validates_length_of :updated_by_id, :maximum => 32 + # validates_datetime_of :updated_date - #define_attributes do - #read_only :bank_identification_number, :created_by_id, :created_date, :gateway_response, - #:gateway_response_code, :updated_by_id, :updated_date - #end - #end -#end + define_attributes do + read_only :bank_identification_number, :created_by_id, :created_date, :gateway_response, + :gateway_response_code, :updated_by_id, :updated_date + end + end +end diff --git a/lib/zuora/objects/product.rb b/lib/zuora/objects/product.rb index ea44d8f..7679714 100644 --- a/lib/zuora/objects/product.rb +++ b/lib/zuora/objects/product.rb @@ -5,7 +5,7 @@ class Product < Base validates_inclusion_of :category, :in => ['DefaultCatalog'], :allow_nil => true validates_length_of :description, :maximum => 500, :allow_nil => true - validates_date_of :effective_start_date, :effective_end_date + # validates_date_of :effective_start_date, :effective_end_date validates_length_of :name, :maximum => 100, :allow_nil => true validates_length_of :sku, :maximum => 50, :allow_nil => true diff --git a/lib/zuora/objects/product_rate_plan.rb b/lib/zuora/objects/product_rate_plan.rb index d5f40a0..097496e 100644 --- a/lib/zuora/objects/product_rate_plan.rb +++ b/lib/zuora/objects/product_rate_plan.rb @@ -4,11 +4,12 @@ class ProductRatePlan < Base has_many :product_rate_plan_charges validates_length_of :description, :maximum => 500, :allow_nil => true - validates_datetime_of :effective_start_date, :effective_end_date + # validates_datetime_of :effective_start_date, :effective_end_date validates_length_of :name, :maximum => 100, :allow_nil => true define_attributes do - read_only :updated_by_id, :updated_date, :created_by_id, :created_date + read_only :updated_by_id, :updated_date, :created_by_id, :created_date, :active_currencies + defer :active_currencies end end end diff --git a/lib/zuora/objects/product_rate_plan_charge.rb b/lib/zuora/objects/product_rate_plan_charge.rb index 7b9da93..5bbb90b 100644 --- a/lib/zuora/objects/product_rate_plan_charge.rb +++ b/lib/zuora/objects/product_rate_plan_charge.rb @@ -16,7 +16,7 @@ class ProductRatePlanCharge < Base INCLUDED_UNITS = ['Tiered Pricing','Tiered with Overage Pricing','Volume Pricing'] OVERAGE_CALCULATION_OPTIONS = %w(EndOfSmoothingPeriod PerBillingPeriod) OVERAGE_UNUSED_UNITS_CREDIT_OPTIONS = %w(NoCredit CreditBySpecificRate) - PRICE_INCREASE_OPTIONS = %w(FromTenantPercentageValue SpecificPercentageValue) + # PRICE_INCREASE_OPTIONS = %w(FromTenantPercentageValue SpecificPercentageValue) REV_REC_TRIGGER_CONDITIONS = %w(ContractEffectiveDate ServiceActivationDate CustomerAcceptanceDate) SMOOTHING_MODELS = %w(RollingWindow Rollover) @@ -37,7 +37,6 @@ class ProductRatePlanCharge < Base validates_numericality_of :bill_cycle_day, :only_integer => true, :allow_nil => true validates_inclusion_of :overage_calculation_option, :in => OVERAGE_CALCULATION_OPTIONS, :allow_nil => true validates_inclusion_of :overage_unused_units_credit_option, :in => OVERAGE_UNUSED_UNITS_CREDIT_OPTIONS, :allow_nil => true - validates_inclusion_of :price_increase_option, :in => PRICE_INCREASE_OPTIONS, :allow_nil => true validates_numericality_of :price_increase_percentage, :only_integer => true, :less_than_or_equal_to => 100, :greater_than_or_equal_to => -100, :allow_nil => true validates_inclusion_of :rev_rec_trigger_condition, :in => REV_REC_TRIGGER_CONDITIONS, :allow_nil => true validates_inclusion_of :smoothing_model, :in => SMOOTHING_MODELS @@ -46,7 +45,7 @@ class ProductRatePlanCharge < Base validates_inclusion_of :use_discount_specific_accounting_code, :in => [true, false], :allow_nil => true define_attributes do - read_only :created_by_id, :created_date, :updated_by_id, :update_date + read_only :created_by_id, :created_date, :updated_by_id, :update_date complex :product_rate_plan_charge_tier_data => :product_rate_plan_charge_tiers end end diff --git a/lib/zuora/objects/rate_plan_charge.rb b/lib/zuora/objects/rate_plan_charge.rb index 5122aa5..63b4c1d 100644 --- a/lib/zuora/objects/rate_plan_charge.rb +++ b/lib/zuora/objects/rate_plan_charge.rb @@ -7,10 +7,10 @@ class RatePlanCharge < Base belongs_to :original, :class_name => 'RatePlanCharge' belongs_to :product_rate_plan_charge belongs_to :rate_plan - + has_many :rate_plan_charge_tiers - CHARGE_MODELS = [ + CHARGE_MODELS = [ "Flat Fee Pricing", "Per Unit Pricing", "Overage Pricing", @@ -31,7 +31,7 @@ class RatePlanCharge < Base validates_numericality_of :bill_cycle_day, :only_integer => true, :greater_than_or_equal_to => 0, :less_than_or_equal_to => 31, :allow_nil => true validates_inclusion_of :bill_cycle_type, :allow_nil => true, :in => %w(DefaultFromCustomer SpecificDayofMonth SubscriptionStartDay ChargeTriggerDay) validates_inclusion_of :billing_period_alignment, :allow_nil => true, :in => %w(AlignToCharge AlignToSubscriptionStart AlignToTermStart) - validates_datetime_of :charged_through_date, :allow_nil => true + # validates_datetime_of :charged_through_date, :allow_nil => true validates_inclusion_of :charge_model, :allow_nil => true, :in => CHARGE_MODELS validates_length_of :charge_number, :maximum => 50 # String validates_inclusion_of :charge_type, :in => %w(OneTime Recurring Usage) @@ -41,8 +41,8 @@ class RatePlanCharge < Base validates_numericality_of :discount_percentage, :allow_nil => true, :greater_than => 0 validates_numericality_of :dmrc, :allow_nil => true validates_numericality_of :dtcv, :allow_nil => true - validates_datetime_of :effective_end_date - validates_datetime_of :effective_start_date + # validates_datetime_of :effective_end_date + # validates_datetime_of :effective_start_date validates_numericality_of :included_units, :greater_than => 0, :if => Proc.new { |rpc| ['Overage','Tiered with Overage Pricing'].include?(rpc.charge_model) } validates_inclusion_of :is_last_segment, :in => [true, false], :allow_nil => true validates_numericality_of :mrr, :allow_nil => true @@ -54,12 +54,12 @@ class RatePlanCharge < Base validates_inclusion_of :overage_unused_units_credit_option, :allow_nil => true, :in => %w(NoCredit CreditBySpecificRate), :if => Proc.new { |rpc| ['Overage','Tiered with Overage Pricing'].include?(rpc.charge_model) } validates_numericality_of :price, :allow_nil => true validates_numericality_of :price_increase_percentage, :less_than_or_equal_to => 100, :greater_than_or_equal_to => -100, :allow_nil => true - validates_datetime_of :processed_through_date, :allow_nil => true + # validates_datetime_of :processed_through_date, :allow_nil => true validates_numericality_of :quantity, :allow_nil => true, :greater_than_or_equal_to => 0 validates_numericality_of :rollover_balance, :allow_nil => true validates_numericality_of :segment, :integer_only => true, :greater_than_or_equal_to => 1 validates_numericality_of :tcv - validates_datetime_of :trigger_date, :allow_nil => true + # validates_datetime_of :trigger_date, :allow_nil => true validates_inclusion_of :trigger_event, :in => %w(ContractEffective CustomerAcceptance ServiceActivation SpecificDate) validates_numericality_of :unused_units_credit_rates, :if => Proc.new { |rpc| ['Overage','Tiered with Overage Pricing'].include?(rpc.charge_model) } validates_numericality_of :up_to_periods, :integer_only => true, :allow_nil => true diff --git a/lib/zuora/objects/refund.rb b/lib/zuora/objects/refund.rb index 0090f66..4ee1d96 100644 --- a/lib/zuora/objects/refund.rb +++ b/lib/zuora/objects/refund.rb @@ -1,35 +1,36 @@ -#module Zuora::Objects - #class Refund < Base - #belongs_to :account - #belongs_to :payment - #belongs_to :payment_method +module Zuora::Objects + class Refund < Base + belongs_to :account + belongs_to :payment + belongs_to :payment_method - #validates_presence_of :amount, :type + validates_presence_of :amount, :type - #validates_length_of :accounting_code, :maximum => 100 - #validates_numericality_of :amount - #validates_length_of :comment, :maximum => 255 - #validates_length_of :created_by_id, :maximum => 32 - #validates_datetime_of :created_date, :allow_nil => true - #validates_length_of :gateway_response, :maximum => 500 - #validates_length_of :gateway_response_code, :maximum => 20 - #validates_inclusion_of :method_type, :in => %w(ACH Cash Check CreditCard Other PayPal WireTransfer DebitCard CreditCardReferenceTransaction) - #validates_length_of :payment_method_id, :maximum => 60 - #validates_datetime_of :refund_date - #validates_datetime_of :refund_transaction_time, :allow_nil => true - #validates_length_of :soft_descriptor, :maximum => 35, :allow_nil => true - #validates_length_of :soft_descriptor_phone, :maximum => 20, :allow_nil => true - #validates_inclusion_of :source_type, :in => %w(Payment CreditBalance), :allow_nil => true - #validates_inclusion_of :status, :in => %w(Canceled Error Processed Processing), :allow_nil => true - #validates_inclusion_of :transferred_to_accouning, :allow_nil => true, :in => %w(Processing Yes Error Ignore) - #validates_inclusion_of :type, :in => %w(Electronic External) - #validates_length_of :updated_by_id, :maximum => 32 - #validates_datetime_of :update_date, :allow_nil => true + validates_length_of :accounting_code, :maximum => 100 + validates_numericality_of :amount + validates_length_of :comment, :maximum => 255 + validates_length_of :created_by_id, :maximum => 32 + # validates_datetime_of :created_date, :allow_nil => true + validates_length_of :gateway_response, :maximum => 500 + validates_length_of :gateway_response_code, :maximum => 20 + validates_inclusion_of :method_type, :in => %w(ACH Cash Check CreditCard Other PayPal WireTransfer DebitCard CreditCardReferenceTransaction) + validates_length_of :payment_method_id, :maximum => 60 + # validates_datetime_of :refund_date + # validates_datetime_of :refund_transaction_time, :allow_nil => true + validates_length_of :soft_descriptor, :maximum => 35, :allow_nil => true + validates_length_of :soft_descriptor_phone, :maximum => 20, :allow_nil => true + validates_inclusion_of :source_type, :in => %w(Payment CreditBalance), :allow_nil => true + validates_inclusion_of :status, :in => %w(Canceled Error Processed Processing), :allow_nil => true + validates_inclusion_of :transferred_to_accouning, :allow_nil => true, :in => %w(Processing Yes Error Ignore) + validates_inclusion_of :type, :in => %w(Electronic External) + validates_length_of :updated_by_id, :maximum => 32 + # validates_datetime_of :update_date, :allow_nil => true - #define_attributes do - #read_only :accounting_code, :created_by_id, :created_date, :gateway_response, - #:gateway_response_code, :reference_id, :refund_number, :refund_transaction_time, - #:status, :updated_by_id, :updated_date - #end - #end -#end + define_attributes do + read_only :accounting_code, :created_by_id, :created_date, :gateway_response, + :gateway_response_code, :reference_id, :refund_number, :refund_transaction_time, + :status, :updated_by_id, :updated_date + deferred_attributes :gateway_option_data, :payment_id, :refund_invoice_payment_data + end + end +end diff --git a/lib/zuora/objects/refund_invoice_payment.rb b/lib/zuora/objects/refund_invoice_payment.rb index c12e922..952a24b 100644 --- a/lib/zuora/objects/refund_invoice_payment.rb +++ b/lib/zuora/objects/refund_invoice_payment.rb @@ -1,18 +1,18 @@ -#module Zuora::Objects - #class RefundInvoicePayment < Base - #belongs_to :invoice_payment - #belongs_to :refund +module Zuora::Objects + class RefundInvoicePayment < Base + belongs_to :invoice_payment + belongs_to :refund - #validates_presence_of :invoice_payment_id, :refund_amount, :refund_id + validates_presence_of :invoice_payment_id, :refund_amount, :refund_id - #validates_length_of :created_by_id, :maximum => 32 - #validates_datetime_of :created_date, :allow_nil => true - #validates_length_of :updated_by_id, :maximum => 32 - #validates_datetime_of :update_date, :allow_nil => true + validates_length_of :created_by_id, :maximum => 32 + # validates_datetime_of :created_date, :allow_nil => true + validates_length_of :updated_by_id, :maximum => 32 + # validates_datetime_of :update_date, :allow_nil => true - #define_attributes do - #read_only :created_by_id, :created_date, :invoice_payment_id, :refund_amount, - #:refund_id, :updated_by_id, :updated_date - #end - #end -#end + define_attributes do + read_only :created_by_id, :created_date, :invoice_payment_id, :refund_amount, + :refund_id, :updated_by_id, :updated_date + end + end +end diff --git a/lib/zuora/objects/subscribe_request.rb b/lib/zuora/objects/subscribe_request.rb index 6a92cc3..edfb460 100644 --- a/lib/zuora/objects/subscribe_request.rb +++ b/lib/zuora/objects/subscribe_request.rb @@ -5,16 +5,16 @@ class SubscribeRequest < Base attr_accessor :bill_to_contact attr_accessor :payment_method attr_accessor :sold_to_contact - attr_accessor :product_rate_plan - attr_accessor :product_rate_plan_id + attr_accessor :product_rate_plans store_accessors :subscribe_options + store_accessors :preview_options validate do |request| request.must_have_usable(:account) request.must_have_usable(:payment_method) request.must_have_usable(:bill_to_contact) - request.must_have_usable(:product_rate_plan) unless request.product_rate_plan_id + request.must_have_usable(:product_rate_plans) request.must_have_new(:subscription) end @@ -29,53 +29,69 @@ def must_have_new(ref) # used to validate nested objects def must_have_usable(ref) obj = self.send(ref) - return errors[ref] << "must be provided" if obj.nil? - if obj.new_record? || obj.changed? - errors[ref] << "is invalid" unless obj.valid? + return errors[ref] << "must be provided" if obj.blank? + obj = obj.is_a?(Array) ? obj : [obj] + obj.each do |object| + if object.new_record? || object.changed? + errors[ref] << "is invalid" unless object.valid? + end end end # Generate a subscription request def create - return false unless valid? + #return false unless valid? result = Zuora::Api.instance.request(:subscribe) do |xml| xml.__send__(zns, :subscribes) do |s| s.__send__(zns, :Account) do |a| - generate_account(a) + generate_object(a, account) 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) + generate_object(pm, payment_method) end s.__send__(zns, :BillToContact) do |btc| - generate_bill_to_contact(btc) + generate_object(btc, bill_to_contact) end + s.__send__(zns, :PreviewOptions) do |po| + generate_preview_options(po) + end unless preview_options.blank? + s.__send__(zns, :SoldToContact) do |btc| - generate_sold_to_contact(btc) + generate_object(btc, sold_to_contact) end unless sold_to_contact.nil? + s.__send__(zns, :SubscribeOptions) do |so| + generate_subscribe_options(so) + end unless 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, product_rate_plan_id || product_rate_plan.id) + product_rate_plans.each do |product_rate_plan| + 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 end + apply_response(result.to_hash, :subscribe_response) end + # method to support backward compatibility of a single + # product_rate_plan + def product_rate_plan=(rate_plan_object) + self.product_rate_plans = [rate_plan_object] + end + protected def apply_response(response_hash, type) @@ -86,50 +102,19 @@ def apply_response(response_hash, type) subscription.clear_changed_attributes! @previously_changed = changes @changed_attributes.clear - return true else self.errors.add(:base, result[:errors][:message]) - return false end + return result end - def generate_bill_to_contact(builder) - if bill_to_contact.new_record? - bill_to_contact.to_hash.each do |k,v| + def generate_object(builder, object) + if object.new_record? + object.to_hash.each do |k,v| builder.__send__(ons, k.to_s.zuora_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.zuora_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.zuora_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.zuora_camelize.to_sym, v) unless v.nil? - end - else - builder.__send__(ons, :Id, payment_method.id) + builder.__send__(ons, :Id, object.id) end end @@ -141,7 +126,13 @@ def generate_subscription(builder) def generate_subscribe_options(builder) subscribe_options.each do |k,v| - builder.__send__(ons, k.to_s.zuora_camelize.to_sym, 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 diff --git a/lib/zuora/objects/subscription.rb b/lib/zuora/objects/subscription.rb index d878186..7586b88 100644 --- a/lib/zuora/objects/subscription.rb +++ b/lib/zuora/objects/subscription.rb @@ -10,18 +10,18 @@ class Subscription < Base :renewal_term, :term_start_date validates_inclusion_of :auto_renew, :in => [true, false] - validates_datetime_of :cancelled_date, :allow_nil => true - validates_datetime_of :contract_acceptance_date, :allow_nil => true - validates_datetime_of :contract_effective_date + # validates_datetime_of :cancelled_date, :allow_nil => true + # validates_datetime_of :contract_acceptance_date, :allow_nil => true + # validates_datetime_of :contract_effective_date validates_numericality_of :initial_term, :only_integer => true, :minimum => 1 validates_inclusion_of :is_invoice_separate, :in => [true, false], :allow_nil => true validates_length_of :name, :maximum => 100 validates_length_of :notes, :maximum => 500, :allow_nil => true - validates_datetime_of :original_created_date, :allow_nil => true + # validates_datetime_of :original_created_date, :allow_nil => true validates_numericality_of :renewal_term, :only_integer => true - validates_datetime_of :service_activation_date, :allow_nil => true - validates_datetime_of :term_end_date, :allow_nil => true - validates_datetime_of :term_start_date + # validates_datetime_of :service_activation_date, :allow_nil => true + # validates_datetime_of :term_end_date, :allow_nil => true + # validates_datetime_of :term_start_date validates_inclusion_of :term_type, :in => ['TERMED', 'EVERGREEN'], :allow_nil => true define_attributes do diff --git a/lib/zuora/objects/usage.rb b/lib/zuora/objects/usage.rb index fd9082a..d4fbef2 100644 --- a/lib/zuora/objects/usage.rb +++ b/lib/zuora/objects/usage.rb @@ -13,8 +13,8 @@ class Usage < Base validates_presence_of :subscription_id, :unless => :subscription_number validates_length_of :subscription_number, :maximum => 255, :unless => :subscription_id - validates_datetime_of :start_date_time, :allow_nil => true - validates_datetime_of :end_date_time, :allow_nil => true + # validates_datetime_of :start_date_time, :allow_nil => true + # validates_datetime_of :end_date_time, :allow_nil => true validates_presence_of :description, :maximum => 255, :allow_nil => true validates_numericality_of :quantity diff --git a/lib/zuora/soap_connector.rb b/lib/zuora/soap_connector.rb index 2b5b60b..08c3b55 100644 --- a/lib/zuora/soap_connector.rb +++ b/lib/zuora/soap_connector.rb @@ -17,11 +17,11 @@ def serialize(xml, key, value) if value.kind_of?(Zuora::Objects::Base) xml.__send__(zns, key.to_sym) do |child| value.to_hash.each do |k, v| - serialize(child, k.to_s.zuora_camelize, v) unless v.nil? + serialize(child, k.to_s.zuora_camelize, convert_value(v)) unless v.nil? end end else - xml.__send__(ons, key.to_sym, value) + xml.__send__(ons, key.to_sym, convert_value(value)) end end @@ -29,7 +29,7 @@ def create Zuora::Api.instance.request(:create) do |xml| xml.__send__(zns, :zObjects, 'xsi:type' => "#{ons}:#{remote_name}") do |a| @model.to_hash.each do |k,v| - serialize(a, k.to_s.zuora_camelize.to_sym, v) unless v.nil? + serialize(a, k.to_s.zuora_camelize.to_sym, convert_value(v)) unless v.nil? end generate_complex_objects(a, :create) end @@ -44,7 +44,7 @@ def update a.__send__(ons, :Id, obj_id) change_syms = @model.changed.map(&:to_sym) obj_attrs.reject{|k,v| @model.read_only_attributes.include?(k) }.each do |k,v| - a.__send__(ons, k.to_s.zuora_camelize.to_sym, v) if change_syms.include?(k) + a.__send__(ons, k.to_s.zuora_camelize.to_sym, convert_value(v)) if change_syms.include?(k) end generate_complex_objects(a, :update) end @@ -63,14 +63,10 @@ def amend xml.__send__(zns, :requests) do |r| r.__send__(zns, :Amendments) do |a| @model.to_hash.each do |k,v| - serialize(a, k.to_s.zuora_camelize.to_sym, v) unless v.nil? + serialize(a, k.to_s.zuora_camelize.to_sym, convert_value(v)) unless v.nil? end generate_complex_objects(a, :create) end - # Implementation adapted from jmoline/zuora 54cdde65a5de761162cbc6bbdd930082349582fb - r.__send__(zns, :AmendOptions) do |ao| - @model.generate_amend_options(ao) - end unless @model.amend_options.blank? end end end @@ -83,7 +79,7 @@ def parse_attributes(type, attrs={}) # definitions, and only handles inline types. # This is a work in progress, and hopefully this # can be removed in the future via proper support. - tdefs = Zuora::Api.instance.client.wsdl.type_definitions + tdefs = Zuora::Api.instance.wsdl.type_definitions klass = attrs['@xsi:type'.to_sym].base_name if klass attrs.each do |a,v| @@ -106,8 +102,27 @@ def parse_attributes(type, attrs={}) attrs.delete_if {|k,v| !available.include?(k) } end + def generate + Zuora::Api.instance.request(:generate) do |xml| + xml.__send__(zns, :zObjects, 'xsi:type' => "#{ons}:#{remote_name}") do |a| + @model.to_hash.each do |k, v| + a.__send__(ons, k.to_s.zuora_camelize.to_sym, convert_value(v)) unless v.nil? + end + end + end + end + protected + # Zuora doesn't like the default string format of ruby dates/times + def convert_value(value) + if [Date, Time, DateTime].any? { |klass| value.is_a?(klass) } + value.strftime('%FT%T') + else + value + end + end + # generate complex objects for inclusion when creating and updating records def generate_complex_objects(builder, action) @model.complex_attributes.each do |var, scope| @@ -122,7 +137,8 @@ def generate_complex_objects(builder, action) td.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil? end when :update - object.to_hash.reject{|k,v| object.read_only_attributes.include?(k) || object.restrain_attributes.include?(k) }.each do |k,v| + object.to_hash.reject{|k,v| object.read_only_attributes.include?(k) || + object.restrain_attributes.include?(k) }.each do |k,v| td.__send__(ons, k.to_s.zuora_camelize.to_sym, v) unless v.nil? end end diff --git a/lib/zuora/sqlite_connector.rb b/lib/zuora/sqlite_connector.rb index 7da1adc..7e23343 100644 --- a/lib/zuora/sqlite_connector.rb +++ b/lib/zuora/sqlite_connector.rb @@ -30,7 +30,7 @@ def create keys = [] values = [] hash.each do |key, value| - keys << key.to_s.camelize + keys << key.to_s.zuora_camelize values << value.to_s end place_holder = ['?'] * keys.length @@ -56,7 +56,7 @@ def update keys = [] values = [] hash.each do |key, value| - keys << "#{key.to_s.camelize}=?" + keys << "#{key.to_s.zuora_camelize}=?" values << value.to_s end keys = keys.join(', ') @@ -120,7 +120,7 @@ def self.create_table(model) table_name = self.table_name(model) attributes = model.attributes - [:id] attributes = attributes.map do |a| - "'#{a.to_s.camelize}' text" + "'#{a.to_s.zuora_camelize}' text" end autoid = "'Id' integer PRIMARY KEY AUTOINCREMENT" attributes.unshift autoid diff --git a/lib/zuora/validations.rb b/lib/zuora/validations.rb index 647fdbb..73db86f 100644 --- a/lib/zuora/validations.rb +++ b/lib/zuora/validations.rb @@ -8,7 +8,7 @@ def self.included(base) class DateTimeValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - unless value.is_a?(Date) + unless [DateTime, Time].any? { |klass| value.is_a?(klass) } record.errors[attribute] << (options[:message] || "is not a valid datetime") end end @@ -16,7 +16,7 @@ def validate_each(record, attribute, value) class DateValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - unless value.is_a?(Date) + unless [Date].any? { |klass| value.is_a?(klass) } record.errors[attribute] << (options[:message] || "is not a valid date") end end diff --git a/lib/zuora/version.rb b/lib/zuora/version.rb index 6b07028..e711667 100644 --- a/lib/zuora/version.rb +++ b/lib/zuora/version.rb @@ -2,9 +2,9 @@ module Zuora class Version - MAJOR = 0 + MAJOR = 1 MINOR = 0 - PATCH = 2 + PATCH = 0 def self.to_s "#{MAJOR}.#{MINOR}.#{PATCH}" diff --git a/spec/factories/accounts.rb b/spec/factories/accounts.rb index b4ed30e..27b01df 100644 --- a/spec/factories/accounts.rb +++ b/spec/factories/accounts.rb @@ -6,7 +6,7 @@ factory :active_account, :parent => :account do after_create do |account| - contact = FactoryGirl.create(:contact, :account => account) + contact = FactoryGirl.create(:contact, :account => account, :country => "GB") account.bill_to = contact account.sold_to = contact account.status = "Active" diff --git a/spec/factories/product_rate_plan_charge_tiers.rb b/spec/factories/product_rate_plan_charge_tiers.rb index 8eda74e..d796f74 100644 --- a/spec/factories/product_rate_plan_charge_tiers.rb +++ b/spec/factories/product_rate_plan_charge_tiers.rb @@ -1,7 +1,6 @@ FactoryGirl.define do factory :product_rate_plan_charge_tier, :class => Zuora::Objects::ProductRatePlanChargeTier do price 0 - active true starting_unit 0 ending_unit 10 end diff --git a/spec/integration/account_management_spec.rb b/spec/integration/account_management_spec.rb index 84e0988..bb57c2b 100644 --- a/spec/integration/account_management_spec.rb +++ b/spec/integration/account_management_spec.rb @@ -15,7 +15,7 @@ describe "adding and manipulating contacts" do it "is supported" do - contact = FactoryGirl.create(:contact, :account => @account) + contact = FactoryGirl.create(:contact, :account => @account, :country => "GB") @account.bill_to = contact @account.sold_to = contact @account.save.should == true diff --git a/spec/integration/subscription_spec.rb b/spec/integration/subscription_spec.rb index 1524318..493bf09 100644 --- a/spec/integration/subscription_spec.rb +++ b/spec/integration/subscription_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe "Subscription" do - before :each do authenticate! @account = FactoryGirl.create(:active_account, :account_number => generate_key) @@ -28,14 +27,15 @@ ) request.should be_valid - request.create.should == true - + response = request.create + response[:success].should == true + subscriptions = @account.subscriptions subscriptions.size.should == 1 subscription = subscriptions.first subscription.should be_valid - + rps = subscription.rate_plans rps.size.should == 1 rp = rps.first @@ -52,4 +52,4 @@ invoice.invoice_adjustments.should == [] end end - + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4590022..5097ed0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,20 +2,21 @@ require 'artifice' require 'digest/md5' require 'factory_girl' -require "rspec" -require 'minitest/autorun' Dir["#{File.dirname(__FILE__)}/../spec/support/**/*.rb"].sort.each { |ext| require ext } Dir["#{File.dirname(__FILE__)}/../spec/factories/*.rb"].sort.each { |ext| require ext } +Zuora.configure(:log => false) + RSpec.configure do |c| - #c.fail_fast = true + c.include Namespace end def generate_key Digest::MD5.hexdigest("#{Time.now}-#{rand}") end + def zuora_namespace(uri) Zuora::Api.instance.client.soap.namespace_by_uri(uri) end @@ -28,12 +29,4 @@ def ons zuora_namespace('http://object.api.zuora.com/') end -# Deal with ActiveModel::Lint Minitest integration; define asserts to use a RSpec style -def assert(thing_to_be_asserted, message = nil) - thing_to_be_asserted.should be_true -end - -def assert_kind_of(klass, obj) - obj.is_a?(klass).should be_true -end diff --git a/spec/support/active_model_lint.rb b/spec/support/active_model_lint.rb index edceafa..eac7c8e 100644 --- a/spec/support/active_model_lint.rb +++ b/spec/support/active_model_lint.rb @@ -1,5 +1,7 @@ shared_examples_for "ActiveModel" do + require 'test/unit/assertions' require 'active_model/lint' + include Test::Unit::Assertions include ActiveModel::Lint::Tests ActiveModel::Lint::Tests.public_instance_methods.map { |method| method.to_s }.grep(/^test/).each do |method| diff --git a/spec/support/mock_response.rb b/spec/support/mock_response.rb index 0c294f6..717b65b 100644 --- a/spec/support/mock_response.rb +++ b/spec/support/mock_response.rb @@ -1,15 +1,17 @@ class MockResponse class << self def responds_with(fixture, status=200) - Zuora::Api.instance.stub(:authenticated?, true) do - responder = proc do |env| - [status, { "Content-Type" => 'text/xml'}, Fixture.response(fixture)] - end + Zuora::Api.instance.stub(:authenticated?).and_return(true) - Artifice.activate_with(responder) do - yield - end + responder = proc do |env| + [status, { "Content-Type" => 'text/xml'}, Fixture.response(fixture)] end + + Artifice.activate_with(responder) do + yield + end + + Zuora::Api.instance.unstub(:authenticated?) end end end diff --git a/spec/support/namespace.rb b/spec/support/namespace.rb new file mode 100644 index 0000000..317bb2e --- /dev/null +++ b/spec/support/namespace.rb @@ -0,0 +1,13 @@ +module Namespace + def zuora_namespace(uri) + Zuora::Api.instance.client.operation(:query).build.send(:namespace_by_uri, uri) + end + + def zns + zuora_namespace('http://api.zuora.com/') + end + + def ons + zuora_namespace('http://object.api.zuora.com/') + end +end diff --git a/spec/zuora/api_spec.rb b/spec/zuora/api_spec.rb index c5e6e97..472bab3 100644 --- a/spec/zuora/api_spec.rb +++ b/spec/zuora/api_spec.rb @@ -6,21 +6,13 @@ Zuora::Api.any_instance.stub(:authenticated?).and_return(true) end - it "has readable production WSDL" do - File.exists?(Zuora::Api::PRODUCTION_WSDL).should be + it "has readable WSDL" do + File.exists?(Zuora::Api::WSDL).should be end - it "has readable sandbox WSDL" do - File.exists?(Zuora::Api::SANDBOX_WSDL).should be - end - - it "uses production WSDL by default" do - Zuora::Api.instance.client.wsdl.endpoint.to_s.should == "https://www.zuora.com/apps/services/a/38.0" - end - - it "can be configured to use sandbox WSDL" do + it "can be configured to use sandbox" do Zuora.configure(:username => 'example', :password => 'test', :sandbox => true) - Zuora::Api.instance.client.wsdl.endpoint.to_s.should == "https://apisandbox.zuora.com/apps/services/a/38.0" + Zuora::Api.instance.client.globals[:endpoint].to_s.should == "https://apisandbox.zuora.com/apps/services/a/78.0" end it "can be configured multiple times" do @@ -56,18 +48,17 @@ MockResponse.responds_with(:invalid_login, 500) do lambda do Zuora.configure(:username => 'example', :password => 'test') - Zuora::Api.instance.request(:example) + Zuora::Api.instance.authenticate! end.should raise_error(Zuora::Fault) end end it "raises exception when IOError is found" do - Zuora::Api.instance.client.should_receive(:request).and_raise(IOError.new) + Zuora::Api.instance.client.should_receive(:call).and_raise(IOError.new) Zuora.configure(:username => 'example', :password => 'test') lambda do - Zuora::Api.instance.request(:example) + Zuora::Api.instance.request(:query) end.should raise_error(Zuora::Fault) end end end - diff --git a/spec/zuora/objects/account_spec.rb b/spec/zuora/objects/account_spec.rb index da239c6..e664f64 100644 --- a/spec/zuora/objects/account_spec.rb +++ b/spec/zuora/objects/account_spec.rb @@ -10,12 +10,7 @@ it "has defined attributes" do subject.attributes.keys.map(&:to_s).sort.should == - ["account_number", "additional_email_addresses", "allow_invoice_edit", "auto_pay", "balance", - "batch", "bcd_setting_option", "bill_cycle_day", "bill_to_id", "communication_profile_id", - "created_by_id", "created_date", "crm_id", "currency", "customer_service_rep_name", - "default_payment_method_id", "id", "invoice_delivery_prefs_email", "invoice_delivery_prefs_print", - "invoice_template_id", "last_invoice_date", "name", "notes", "payment_gateway", "payment_term", - "purchase_order_number", "sales_rep_name", "sold_to_id", "status", "updated_by_id", "updated_date"] + ["account_number", "additional_email_addresses", "allow_invoice_edit", "auto_pay", "balance", "batch", "bcd_setting_option", "bill_cycle_day", "bill_to_id", "communication_profile_id", "created_by_id", "created_date", "crm_id", "currency", "customer_service_rep_name", "default_payment_method_id", "id", "invoice_delivery_prefs_email", "invoice_delivery_prefs_print", "invoice_template_id", "last_invoice_date", "name", "notes", "payment_gateway", "payment_term", "purchase_order_number", "sales_rep_name", "sold_to_id", "status", "tax_company_code", "tax_exempt_certificate_id", "tax_exempt_certificate_type", "tax_exempt_description", "tax_exempt_effective_date", "tax_exempt_expiration_date", "tax_exempt_issuing_jurisdiction", "tax_exempt_status", "updated_by_id", "updated_date", "vat_id"] end it "has read only attributes" do @@ -85,16 +80,6 @@ with_value(/select .+ from Account where Id = 'test' and Name = 'Bob'/) end end - - it "supports disjunctions in hash based lookups" do - MockResponse.responds_with(:account_find_success) do - Zuora::Objects::Account.where(:id => ['test', 'Bob']) - xml = Zuora::Api.instance.last_request - ns = zuora_namespace('http://api.zuora.com/') - xml.should have_xml("//env:Body/#{zns}:query/#{zns}:queryString"). - with_value(/select .+ from Account where Id = 'test' or Id = 'Bob'/) - end - end end describe "updating a remote object" do diff --git a/spec/zuora/objects/amendment_spec.rb b/spec/zuora/objects/amendment_spec.rb index 8bbf04e..950549a 100644 --- a/spec/zuora/objects/amendment_spec.rb +++ b/spec/zuora/objects/amendment_spec.rb @@ -1,44 +1,20 @@ require 'spec_helper' describe Zuora::Objects::Amendment do - it "validates datetime of several attributes" do - subject.status = 'PendingAcceptance' # required for service_activation_date - [:contract_effective_date, :customer_acceptance_date, :effective_date, :service_activation_date].each do |attr| - subject.send("#{attr}=", 'invalid') - subject.should_not be_valid - subject.errors[attr].should include('is not a valid datetime') - end - end - - it "validates date of term_start_date" do - subject.type = 'TermsAndConditions' - subject.term_start_date = 'invalid' - subject.should_not be_valid - subject.errors[:term_start_date].should include('is not a valid date') - end - - it "supports subscription options" do - MockResponse.responds_with(:subscription_find_success) do - subscription = Zuora::Objects::Subscription.find('stub') - subject.subscription = subscription - @end_date = subscription.subscription_end_date - end - subject.status = "Completed" - subject.type = "TermsAndConditions" - subject.name = "Change Terms" - subject.contract_effective_date = @end_date + 1.day - subject.term_start_date = @end_date + 1.day - subject.initial_term = 1 - subject.renewal_term = 1 - subject.amend_options = { generate_invoice: false } - - MockResponse.responds_with(:amendment_success) do - subject.should be_valid - subject.create.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('false') - end + #date validation has changed + # it "validates datetime of several attributes" do + # subject.status = 'PendingAcceptance' # required for service_activation_date + # [:contract_effective_date, :customer_acceptance_date, :effective_date, :service_activation_date].each do |attr| + # subject.send("#{attr}=", 'invalid') + # subject.should_not be_valid + # subject.errors[attr].should include('is not a valid datetime') + # end + # end + # + # it "validates date of term_start_date" do + # subject.type = 'TermsAndConditions' + # subject.term_start_date = 'invalid' + # subject.should_not be_valid + # subject.errors[:term_start_date].should include('is not a valid date') + # end end diff --git a/spec/zuora/objects/contact_spec.rb b/spec/zuora/objects/contact_spec.rb index 16b5cbb..0843fde 100644 --- a/spec/zuora/objects/contact_spec.rb +++ b/spec/zuora/objects/contact_spec.rb @@ -35,11 +35,14 @@ end context "when persisted record" do + before :each do + subject.stub(:new_record? => false) + + subject.should_not be_valid + end + it "requires account_id" do - subject.stub(:new_record?, false) do - subject.should_not be_valid - subject.errors[:account_id].should include("can't be blank") - end + subject.errors[:account_id].should include("can't be blank") end end end diff --git a/spec/zuora/objects/invoice_spec.rb b/spec/zuora/objects/invoice_spec.rb index f673124..1f2d2ed 100644 --- a/spec/zuora/objects/invoice_spec.rb +++ b/spec/zuora/objects/invoice_spec.rb @@ -2,19 +2,19 @@ describe Zuora::Objects::Invoice do - it "validates datetime of several attributes" do - [:due_date, :invoice_date, :last_email_sent_date, :posted_date, :target_date, :updated_date,].each do |attr| - subject.errors.clear - subject.send("#{attr}=", 'invalid') - subject.should_not be_valid - subject.errors[attr].should include('is not a valid datetime') - end - [:due_date, :invoice_date, :last_email_sent_date, :posted_date, :target_date, :updated_date,].each do |attr| - subject.errors.clear - value = DateTime.parse('2011-12-28T17:23:27.000-08:00') - subject.send("#{attr}=", value) - subject.errors[attr].should_not include('is not a valid datetime'), "attribute: #{attr}\tvalue: #{value.class} #{value}" - end - end + # it "validates datetime of several attributes" do + # [:due_date, :invoice_date, :last_email_sent_date, :posted_date, :target_date, :updated_date,].each do |attr| + # subject.errors.clear + # subject.send("#{attr}=", 'invalid') + # subject.should_not be_valid + # subject.errors[attr].should include('is not a valid datetime') + # end + # [:due_date, :invoice_date, :last_email_sent_date, :posted_date, :target_date, :updated_date,].each do |attr| + # subject.errors.clear + # value = DateTime.parse('2011-12-28') + # subject.send("#{attr}=", value) + # subject.errors[attr].should_not include('is not a valid datetime'), "attribute: #{attr}\tvalue: #{value.class} #{value}" + # end + # end end diff --git a/spec/zuora/objects/product_rate_plan_charge_spec.rb b/spec/zuora/objects/product_rate_plan_charge_spec.rb index f64917d..e24c046 100644 --- a/spec/zuora/objects/product_rate_plan_charge_spec.rb +++ b/spec/zuora/objects/product_rate_plan_charge_spec.rb @@ -63,14 +63,12 @@ tier1 = Zuora::Objects::ProductRatePlanChargeTier.new do |t| t.price = 0 - t.active = true t.starting_unit = 0 t.ending_unit = 10 end tier2 = Zuora::Objects::ProductRatePlanChargeTier.new do |t| t.price = 50 - t.active = true t.starting_unit = 11 t.ending_unit = 20 end @@ -88,7 +86,6 @@ xml = Zuora::Api.instance.last_request xml.should have_xml("//env:Body/#{zns}:create/#{zns}:zObjects/#{ons}:ProductRatePlanChargeTierData") xml.should have_xml("//#{ons}:ProductRatePlanChargeTierData/#{zns}:ProductRatePlanChargeTier") - xml.should have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:Active").with_value(true) xml.should have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:Price").with_value(50) xml.should have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:StartingUnit").with_value(11) xml.should have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:EndingUnit").with_value(20) @@ -101,8 +98,8 @@ @prpct.map(&:new_record?).should be_none, 'complex objects should not be new records after save' @prpc.product_rate_plan_charge_tiers.first.price = 20 - @prpc.product_rate_plan_charge_tiers.first.price.should == 20 - + @prpc.product_rate_plan_charge_tiers.first.price.should == 20 + MockResponse.responds_with(:product_rate_plan_charge_update_success) do @prpc.save.should == true end @@ -111,12 +108,11 @@ xml.should have_xml("//env:Body/#{zns}:update/#{zns}:zObjects/#{ons}:ProductRatePlanChargeTierData") xml.should have_xml("//env:Body/#{zns}:update/#{zns}:zObjects/#{ons}:Id") xml.should have_xml("//#{ons}:ProductRatePlanChargeTierData/#{zns}:ProductRatePlanChargeTier") - xml.should have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:Active").with_value(true) xml.should have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:Price").with_value(20) xml.should_not have_xml("//#{zns}:ProductRatePlanChargeTier/#{zns}:Id") xml.should_not have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:StartingUnit") xml.should_not have_xml("//#{zns}:ProductRatePlanChargeTier/#{ons}:EndingUnit") - + MockResponse.responds_with(:product_rate_plan_charge_destroy_success) do @prpc.destroy end diff --git a/spec/zuora/objects/subscribe_request_spec.rb b/spec/zuora/objects/subscribe_request_spec.rb index 3eb6b5f..0efa98d 100644 --- a/spec/zuora/objects/subscribe_request_spec.rb +++ b/spec/zuora/objects/subscribe_request_spec.rb @@ -10,6 +10,75 @@ end end + describe "#product_rate_plan=" do + it "should assign product_rate_plans as an array containing the object" do + MockResponse.responds_with(:payment_method_credit_card_find_success) do + @product_rate_plan = Zuora::Objects::ProductRatePlan.find('stub') + end + request = Zuora::Objects::SubscribeRequest.new + request.product_rate_plan = @product_rate_plan + request.product_rate_plans.should eql [@product_rate_plan] + end + end + + describe "validations" do + describe "#must_have_usable" do + context "on account (being a reasonable representation of non-array objects)" do + before do + @account = Zuora::Objects::Account.new + @request = Zuora::Objects::SubscribeRequest.new(:account => @account) + end + + it "should add errors when there are problems with account" do + @account.should_receive(:valid?).and_return(false) + @request.must_have_usable(:account) + @request.errors[:account].should include("is invalid") + end + + it "should not add errors when there are no problems with account" do + @account.should_receive(:valid?).and_return(true) + @request.must_have_usable(:account) + @request.errors[:account].should be_blank + end + end + + context "on product_rate_plans (being an array pbject)" do + before do + @rate_plan1 = Zuora::Objects::ProductRatePlan.new + @rate_plan2 = Zuora::Objects::ProductRatePlan.new + @request = Zuora::Objects::SubscribeRequest.new(:product_rate_plans => [@rate_plan1, @rate_plan2]) + end + + it "should add errors when there are no rate plans" do + @request.product_rate_plans = nil + @request.must_have_usable(:product_rate_plans) + @request.errors[:product_rate_plans].should include("must be provided") + end + + it "should add errors when there are problems with the first rate plan" do + @rate_plan1.should_receive(:valid?).and_return(false) + @rate_plan2.should_receive(:valid?).and_return(true) + @request.must_have_usable(:product_rate_plans) + @request.errors[:product_rate_plans].should include("is invalid") + end + + it "should add errors when there are problems with the second rate plan" do + @rate_plan1.should_receive(:valid?).and_return(true) + @rate_plan2.should_receive(:valid?).and_return(false) + @request.must_have_usable(:product_rate_plans) + @request.errors[:product_rate_plans].should include("is invalid") + end + + it "should not add errors when there are no problems with the rate plans" do + @rate_plan1.should_receive(:valid?).and_return(true) + @rate_plan2.should_receive(:valid?).and_return(true) + @request.must_have_usable(:product_rate_plans) + @request.errors[:product_rate_plans].should be_blank + end + end + end + end + describe "generating a request" do before do MockResponse.responds_with(:account_find_success) do @@ -25,7 +94,7 @@ end MockResponse.responds_with(:payment_method_credit_card_find_success) do - subject.product_rate_plan = Zuora::Objects::ProductRatePlan.find('stub') + subject.product_rate_plans = [Zuora::Objects::ProductRatePlan.find('stub')] end subject.subscription = FactoryGirl.build(:subscription) @@ -34,7 +103,8 @@ it "provides properly formatted xml when using existing objects" do MockResponse.responds_with(:subscribe_request_success) do subject.should be_valid - subject.create.should == true + sub_resp = subject.create + sub_resp[:success].should == true end xml = Zuora::Api.instance.last_request @@ -50,35 +120,13 @@ xml.should_not have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{ons}:SubscribeOptions") end - it "provides properly formatted xml when using existing objects or references" do - MockResponse.responds_with(:subscribe_request_success) do - # We should be able to generate the request with either the materialized ProductRatePlan or just its ID. - subject.product_rate_plan = nil - subject.product_rate_plan_id = '4028e48834aa10a30134c50f40901ea7' - - subject.should be_valid - subject.create.should == true - end - - xml = Zuora::Api.instance.last_request - xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:Account/#{ons}:Id"). - with_value('4028e488348752ce0134876a25867cb2') - xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:PaymentMethod/#{ons}:Id"). - with_value('4028e48834aa10a30134c50f40901ea7') - xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:BillToContact/#{ons}:Id"). - with_value('4028e4873491cc770134972e75746e4c') - xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:SubscriptionData/#{zns}:Subscription") - xml.should have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{zns}:SubscriptionData/#{zns}:RatePlanData/#{zns}:RatePlan/#{ons}:ProductRatePlanId"). - with_value('4028e48834aa10a30134c50f40901ea7') - xml.should_not have_xml("//env:Body/#{zns}:subscribe/#{zns}:subscribes/#{ons}:SubscribeOptions") - end - it "provides full account info when new object" do subject.account = FactoryGirl.build(:account) MockResponse.responds_with(:subscribe_request_success) do subject.should be_valid - subject.create.should == true + sub_resp = subject.create + sub_resp[:success].should == true end xml = Zuora::Api.instance.last_request @@ -93,7 +141,8 @@ MockResponse.responds_with(:subscribe_request_success) do subject.should be_valid - subject.create.should == true + sub_resp = subject.create + sub_resp[:success].should == true end xml = Zuora::Api.instance.last_request @@ -107,7 +156,8 @@ MockResponse.responds_with(:subscribe_request_success) do subject.should be_valid - subject.create.should == true + sub_resp = subject.create + sub_resp[:success].should == true end xml = Zuora::Api.instance.last_request @@ -121,7 +171,8 @@ it "handles applying subscribe failures messages" do MockResponse.responds_with(:subscribe_request_failure) do subject.should be_valid - subject.create.should == false + sub_resp = subject.create + sub_resp[:success].should == false subject.errors[:base].should include('Initial Term should be greater than zero') end end @@ -130,18 +181,20 @@ MockResponse.responds_with(:subscribe_request_success) do subject.subscribe_options = {:generate_invoice => true, :process_payments => true} subject.should be_valid - subject.create.should == true + sub_resp = subject.create + sub_resp[:success].should == true 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 it "applies valid response data to the proper nested objects and resets dirty" do MockResponse.responds_with(:subscribe_request_success) do subject.should be_valid - subject.create.should == true + sub_resp = subject.create + sub_resp[:success].should == true subject.subscription.should_not be_changed subject.subscription.should_not be_new_record end diff --git a/spec/zuora/sqlite_connector_spec.rb b/spec/zuora/sqlite_connector_spec.rb index a4fc53e..e9b448a 100644 --- a/spec/zuora/sqlite_connector_spec.rb +++ b/spec/zuora/sqlite_connector_spec.rb @@ -21,7 +21,7 @@ table_name = described_class.table_name(m) table = @db.table_info(table_name) columns = table.map {|t| t["name"] } - camel_attrs = m.attributes.map { |a| a.to_s.camelize } + camel_attrs = m.attributes.map { |a| a.to_s.zuora_camelize } (camel_attrs - columns).should == [] end end @@ -48,22 +48,11 @@ @product2.create end - it "returns matching records for single term" do + it "returns matching records" do records = @model.where(:name => 'Product One') records.first.name.should == @product1.name records.first.id.should == @product1.id end - - it "returns matching records for multiple terms" do - # Sort the results because determinism in tests is a fine quality. - records = @model.where(:name => ['Product One', 'Another One']).sort { |x,y| x.name <=> y.name } - - records.first.name.should == @product2.name - records.first.id.should == @product2.id - - records.last.name.should == @product1.name - records.last.id.should == @product1.id - end end describe :create do @@ -129,15 +118,15 @@ end end - describe "factories" do - before :each do - @product = Factory(:product) - end + describe "factories" do + before :each do + @product = Factory(:product) + end - it "should exists" do - @product.should be - end + it "should exists" do + @product.should be end + end end diff --git a/spec/zuora/validations_spec.rb b/spec/zuora/validations_spec.rb index f6c34ca..70378bc 100644 --- a/spec/zuora/validations_spec.rb +++ b/spec/zuora/validations_spec.rb @@ -15,9 +15,9 @@ class ExampleObject end describe "validating date" do - it "allows date and time related objects" do - [Date.today, DateTime.now, Time.now].each do |val| - @obj.birthday = Date.today + it "allows date objects" do + [Date.today].each do |val| + @obj.birthday = val @obj.valid? @obj.errors[:birthday].should be_blank end @@ -34,8 +34,8 @@ class ExampleObject describe "validating date_time" do it "allows date and time related objects" do - [Date.today, DateTime.now, Time.now].each do |val| - @obj.validated_at = Date.today + [DateTime.now, Time.now].each do |val| + @obj.validated_at = val @obj.valid? @obj.errors[:validated_at].should be_blank end diff --git a/wsdl/sandbox/zuora.a.38.0.wsdl b/wsdl/sandbox/zuora.a.38.0.wsdl deleted file mode 100644 index c7aa891..0000000 --- a/wsdl/sandbox/zuora.a.38.0.wsdl +++ /dev/null @@ -1,1516 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wsdl/production/zuora.a.38.0.wsdl b/wsdl/zuora.a.38.0.wsdl similarity index 75% rename from wsdl/production/zuora.a.38.0.wsdl rename to wsdl/zuora.a.38.0.wsdl index be29414..bd09702 100644 --- a/wsdl/production/zuora.a.38.0.wsdl +++ b/wsdl/zuora.a.38.0.wsdl @@ -2,26 +2,26 @@ - + - + - - - - + + + + @@ -36,14 +36,11 @@ - - + + - - - @@ -57,13 +54,13 @@ - - + + - + @@ -73,27 +70,27 @@ - - - + + + - + - - - - + + + + - - + + - + @@ -105,8 +102,8 @@ - - + + @@ -120,12 +117,12 @@ - - + + - + @@ -134,9 +131,9 @@ - - - + + + @@ -149,8 +146,8 @@ - - + + @@ -164,8 +161,8 @@ - - + + @@ -177,8 +174,8 @@ - - + + @@ -226,8 +223,8 @@ - - + + @@ -247,8 +244,8 @@ - - + + @@ -257,13 +254,13 @@ - - + + - - + + @@ -281,7 +278,7 @@ - + @@ -296,7 +293,7 @@ - + @@ -315,7 +312,7 @@ - + @@ -326,13 +323,13 @@ - - + + - - + + @@ -344,13 +341,13 @@ - + - - + + @@ -370,8 +367,8 @@ - - + + @@ -391,7 +388,7 @@ - + @@ -409,8 +406,8 @@ - - + + @@ -436,7 +433,7 @@ - + @@ -445,9 +442,9 @@ - - - + + + @@ -457,15 +454,15 @@ - - + + - - + + @@ -474,15 +471,15 @@ - - + + - - + + @@ -496,10 +493,10 @@ - + - - + + @@ -519,9 +516,9 @@ - - - + + + @@ -531,8 +528,8 @@ - - + + @@ -541,8 +538,8 @@ - - + + @@ -564,13 +561,13 @@ - - + + - - + + @@ -588,8 +585,8 @@ - - + + @@ -620,12 +617,12 @@ - - - + + + - - + + @@ -634,8 +631,8 @@ - - + + @@ -643,8 +640,8 @@ - - + + @@ -658,13 +655,13 @@ - - + + - + @@ -675,103 +672,103 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + - - + + - - + + @@ -801,11 +798,11 @@ - + - - - + + + @@ -819,40 +816,40 @@ - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -882,13 +879,13 @@ - - - - - - - + + + + + + + @@ -1092,63 +1089,63 @@ - - - + + + - - + + + + + + + + + + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - + - + + + - - - - - - - - - - - - - + + + + + + + + - + + + + + + - + + + + + + + @@ -1195,7 +1192,7 @@ - + @@ -1270,19 +1267,19 @@ - + - - - - - - + + + + + + @@ -1320,13 +1317,13 @@ - - - - - - - + + + + + + + @@ -1334,16 +1331,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -1462,7 +1459,7 @@ - + @@ -1474,8 +1471,8 @@ - - + + @@ -1487,8 +1484,8 @@ - - + + diff --git a/wsdl/zuora.a.78.0.wsdl b/wsdl/zuora.a.78.0.wsdl new file mode 100644 index 0000000..fa22cda --- /dev/null +++ b/wsdl/zuora.a.78.0.wsdl @@ -0,0 +1,2217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gets the next batch of sObjects from a query + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zuora.gemspec b/zuora.gemspec index 211a31a..d050613 100644 --- a/zuora.gemspec +++ b/zuora.gemspec @@ -13,16 +13,19 @@ Gem::Specification.new do |s| s.description = %q{Zuora - Easily integrate the Zuora SOAP API using ruby objects.} s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.extra_rdoc_files = [ "README.md" ] + s.licenses = ["Apache 2.0"] + s.extra_rdoc_files = ["README.md"] - s.add_runtime_dependency(%q, [">= 0.9.8"]) - s.add_runtime_dependency(%q, [">= 4.0.0"]) - s.add_runtime_dependency(%q, [">= 4.0.0"]) + s.add_runtime_dependency(%q, ["~> 3.2.0"]) + s.add_runtime_dependency(%q, ["~> 2.3.0"]) + s.add_runtime_dependency(%q, [">= 3.0.0"]) + s.add_runtime_dependency(%q, [">= 3.0.0"]) s.add_runtime_dependency(%q, ['~> 0.2.6']) - s.add_development_dependency(%q, ["~> 0.8.7"]) + + s.add_development_dependency(%q, ["~> 10.1.0"]) s.add_development_dependency(%q, ["~> 0.6.0"]) s.add_development_dependency(%q, ["~> 0.6.0"]) s.add_development_dependency(%q, ["~> 0.7.5"]) @@ -31,5 +34,6 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, ["~> 2.6.4"]) s.add_development_dependency(%q, ["~> 0.4.1"]) s.add_development_dependency(%q, ["~> 1.3.0"]) - s.add_development_dependency(%q) + s.add_development_dependency('byebug') + s.add_development_dependency('test-unit') end