Git Product home page Git Product logo

active_zuora's Introduction

active_zuora - Auto-Generated ActiveModel Interface for Zuora

TravisCI Code Climate

Use Zuora's API like ActiveRecord. Auto-generate all the classes from the wsdl file, or easily declare your own.

Active Zuora Version 1

This repostiory contains >= Version 2 of Active Zuora

Version 1 can be found at https://github.com/sportngin/active_zuora_v1

Thread Safety

2.0.X versions of Active Zuora are not thread safe. They depend on a version of Savon that is does not work with threads.

As of 2.1.0 Active Zuora is now depending on a thread safe version of Savon

Configuration

    ActiveZuora.configure(
      :username => '[email protected]',
      :password => 'password'
    )

Enable SOAP logging to stderr, provide your own wsdl file or add custom fields to a list of filtered fields.

    ActiveZuora.configure(
      :username => '[email protected]',
      :password => 'password',
      :log => true,
      :log_filters => [:password, :SessionHeader, :mySecretCustomField1, :mySecretCustomField1], # Defaults to [:password, :SessionHeader]
      :wsdl => 'path/to/zuora.wsdl'
    )

Override the default endpoint or host loaded from the wsdl

ActiveZuora::Base.connection.soap_client.wsdl.endpoint.host = "www.zuora.com" if Rails.env.production?

To add custom headers to your Zuora requests, you can use the following pattern

ActiveZuora::Base.connection.custom_header = { 'X-Foo' => 'Bar' }

Defining Classes

You can auto-generate all your Zuora classes from the wsdl file. It will generate all Z-Objects, like Account and Subscription, and Zuora Complex objects, such as SubscribeRequest.

ActiveZuora.generate_classes

By default, it will generate the classes inside the ActiveZuora module. But you can specify a different nesting if you'd like.

ActiveZuora.generate_classes :inside => SomeOtherModule

Or, if you prefer, you can define your ZObjects or Complex Types manually.

class Account

  include ActiveZuora::ZObject

  field :name, :string
  field :auto_pay, :boolean, :default => true
  field :balance, :decimal
  field :created_date, :datetime

  has_many :subscriptions, :order => :name
  has_many :active_subscriptions, :class_name => 'Subscription',
    :conditions => { :status => 'Active' },
    :order => [ :name, :desc ]
  belongs_to :parent, :class_name => 'Account'
  has_many :children, :class_name => 'Account', :foreign_key => :parent_id, :inverse_of => :parent

  validates_presence_of :name

end

class SubscriptionData

  include ActiveZuora::Base

  field :subscription, :object
  field :rate_plan_data, :object, :array => true

end

Saving, Updating, and Deleting

These familiar functions are available: save, create, and update_attributes, along with ! versions that raise exceptions upon failure.

account = ActiveZuora::Account.new :name => "Frank's Pest Control"
account.new_record?
account.save

account = ActiveZuora::Account.create! :name => "Frank's Pest Control"
account.update_attributes :auto_pay => false, :currency => "USD"

Changes are also tracked.

account = ActiveZuora::Account.new :name => "Frank's Pest Control"
account.changes # { :name => [nil, "Frank's Pest Control"] }
account.save!
account.changes # []

Errors are captured using ActiveModel::Validations, or from error messages received from the server.

account = ActiveZuora::Account.new
account.save # false
account.errors # { :base => ["Missing attribute: Name"] } # Returned from server.

Delete a record with #delete.

account.delete

Querying

ActiveZuora::Account.find(id)

ActiveZuora::Account.where(:name => "Frank's Pest Control").all

ActiveZuora::Account.where(:name => { :like => '%Pest Control' }).count

ActiveZuora::Account.where(:auto_pay => true).or(:balance => 0).all

ActiveZuora::Account.select(:id, :name).where(:created_date => { "<" => Date.yesterday })

There is no "order by" clause in the ZQL query language, but ActiveZuora's query system can post-sort results for you:

ActiveZuora::Account.where(:status => "Active").order(:name)

ActiveZuora::Account.where(:status => "Draft").order(:created_date, :desc)

By default, every Query object caches the results once you call an array-like method on it. However, if you know you'll have a very large result set and you just want to iterate through them without keeping them, you can use find_each.

ActiveZuora::Account.where(:status => "Active").find_each do |account|
  ...
end

Scopes

ActiveZuora::Account.instance_eval do
  scope :active, :status => "Active"
  scope :draft, where(:status => "Draft")
  scope :since, lambda { |datetime| where(:created_date => { ">=" => datetime }) }
end

ActiveZuora::Account.select(:id).draft.since(Date.new 2012).to_zql
# => "select Id from Account where Status = 'Draft' and CreatedDate >= '2012-01-01T00:00:00+08:00'"

Like ActiveRecord, you can also chain any class method on the ZObject, since named scopes are nothing more than class methods that return a Relation object.

Update or Delete Using Queries

You can update or delete multiple records at once. The following command issues two requests to the Zuora API server: the first to query for the records, and the second to update them all at once. The method returns the count of records that were successfully updated.

ActiveZuora::Account.where(:status => "Draft").update_all :status => "Active" # 56

You can also use a block to update your records, in case your updates depend on the records themselves.

ActiveZuora::Account.where(:status => "Draft").update_all do |account|
  account.name += " (#{account.currency})"
end

You can also delete all records matching a query as well. The method returns the amount of records deleted.

ActiveZuora::Account.where(:status => "Draft").delete_all # 56

Batch Subscribe

You can submit up to 50 subscribe requests on a single subscribe call per the Zuora documentation. To batch subscribe requests, use the CollectionProxy to build a collection of subscribe requests, then call batch_subscribe

ActiveZuora::CollectionProxy.new([ActiveZuora::SubscribeRequest.new({account: {}, bill_to: {}, subscription_data:{}}), 
                                  ActiveZuora::SubscribeRequest.new({account: {}, bill_to: {}, subscription_data:{}})]).batch_subscribe

License

Active Zuora is released under the MIT license:

http://www.opensource.org/licenses/MIT

Support

Bug reports and feature requests can be filed as github issues here:

https://github.com/sportngin/active_zuora/issues

active_zuora's People

Contributors

aossowski avatar billthompson avatar cdelrosario avatar geapi avatar iamdavidovich avatar jakcharlton avatar jlleblanc avatar jonnymacs avatar jphenow avatar nvd avatar pete2786 avatar rewinfrey avatar rudasa avatar scottpayne-ffx avatar timpbrenner avatar timsegraves avatar vickys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

active_zuora's Issues

Logging - Password Filtering

Currently Active Zuora will log plaintext password, when making login calls. Savon2 allows filters with the following, as shown here, however there doesn't seem to be an equivalent API for Savon 1.2

Savon.client(filters: [:password])

Would it be possible to filter out this password within the current Active Zuora architecture?

Rails 5.2 :`FrozenError: can't modify frozen ActiveSupport::HashWithIndifferentAccess`

Steps to reproduce

  1. Install Ruby 2.4.6 (or whatever Ruby version Rails 5.2 supports like Ruby 2.2+)
  2. export ZUORA_USER=<zuora_username> ; export ZUORA_PASS=<zuora_password> to run Integration tests
  3. git clone https://github.com/sportngin/active_zuora
  4. cd active_zuora
  5. bundle install
  6. bundle exec rspec

Expected behavior

All of integration tests pass.

Actual behavior

8 specs fail due to FrozenError: can't modify frozen ActiveSupport::HashWithIndifferentAccess. I think it is related with # frozen_string_literal: true magic comment introduced since Rails 5.2.
https://github.com/rails/rails/blob/v5.2.3/activesupport/lib/active_support/hash_with_indifferent_access.rb#L1

$ bundle exec rspec

Create Account
  can create an account (FAILED - 1)

ActiveZuora::Base
  #fields_order
    When the value of a field is null, it should be the first
    When the field name is id, it should be after the nil value fields but before all other fields

BelongsToAssociations
  should define a attribute assignment method method for the object
  should define a attribute assignment method for the object id

ActiveZuora::CollectionProxy
  should initialize
  should respond to enumerable methods
  should respond to the batch_subscribe method

ActiveZuora::Connection
  custom header
    passes the regular header if not set
    merges in a custom header if set
  login
    when a custom header is set
      uses the custom header
    when a custom header is not set
      does not use the custom header

ActiveZuora::DateField
  #type_cast
    returns nil if provided nil
    returns a date when given a datetime object
    returns a date when given a date object
  #build_xml
    handles a nil value
    handles a date value

HasManyRelations
  can specify conditions and order (FAILED - 2)
  can behave like an array (FAILED - 3)
  can respond to functions on the Relation (FAILED - 4)

LazyAttr
  should fetch a lazy loaded attribute from the api
  should should not refetch an attribute after it's been loaded once

Subscribe
  Can successfully subscribe and amend using a new account (FAILED - 5)
  Can successfully subscribe and generate a bill preview and an invoice (FAILED - 6)
  Can successfully batch subscribe from a collection proxy of subscribe requests and generate an invoice for the first subscription (FAILED - 7)

ZObject
  can be created, queried, updated, and destroyed (FAILED - 8)

Failures:

  1) Create Account can create an account
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./spec/account_integration_spec.rb:30:in `block (4 levels) in <top (required)>'
     # ./spec/spec_helper.rb:27:in `now'
     # ./spec/account_integration_spec.rb:29:in `block (3 levels) in <top (required)>'

  2) HasManyRelations can specify conditions and order
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./lib/active_zuora/persistence.rb:17:in `save!'
     # ./lib/active_zuora/persistence.rb:79:in `tap'
     # ./lib/active_zuora/persistence.rb:79:in `create!'
     # ./spec/has_many_integration_spec.rb:8:in `block (3 levels) in <top (required)>'

  3) HasManyRelations can behave like an array
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./lib/active_zuora/persistence.rb:17:in `save!'
     # ./lib/active_zuora/persistence.rb:79:in `tap'
     # ./lib/active_zuora/persistence.rb:79:in `create!'
     # ./spec/has_many_integration_spec.rb:8:in `block (3 levels) in <top (required)>'

  4) HasManyRelations can respond to functions on the Relation
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./lib/active_zuora/persistence.rb:17:in `save!'
     # ./lib/active_zuora/persistence.rb:79:in `tap'
     # ./lib/active_zuora/persistence.rb:79:in `create!'
     # ./spec/has_many_integration_spec.rb:8:in `block (3 levels) in <top (required)>'

  5) Subscribe Can successfully subscribe and amend using a new account
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./lib/active_zuora/persistence.rb:17:in `save!'
     # ./lib/active_zuora/persistence.rb:79:in `tap'
     # ./lib/active_zuora/persistence.rb:79:in `create!'
     # ./spec/subscribe_integration_spec.rb:8:in `block (3 levels) in <top (required)>'

  6) Subscribe Can successfully subscribe and generate a bill preview and an invoice
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./lib/active_zuora/persistence.rb:17:in `save!'
     # ./lib/active_zuora/persistence.rb:79:in `tap'
     # ./lib/active_zuora/persistence.rb:79:in `create!'
     # ./spec/subscribe_integration_spec.rb:8:in `block (3 levels) in <top (required)>'

  7) Subscribe Can successfully batch subscribe from a collection proxy of subscribe requests and generate an invoice for the first subscription
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./lib/active_zuora/persistence.rb:17:in `save!'
     # ./lib/active_zuora/persistence.rb:79:in `tap'
     # ./lib/active_zuora/persistence.rb:79:in `create!'
     # ./spec/subscribe_integration_spec.rb:8:in `block (3 levels) in <top (required)>'

  8) ZObject can be created, queried, updated, and destroyed
     Failure/Error: changed_attributes.clear

     FrozenError:
       can't modify frozen ActiveSupport::HashWithIndifferentAccess
     # ./lib/active_zuora/fields.rb:55:in `clear'
     # ./lib/active_zuora/fields.rb:55:in `clear_changed_attributes'
     # ./lib/active_zuora/persistence.rb:59:in `create'
     # ./lib/active_zuora/persistence.rb:13:in `save'
     # ./spec/zobject_integration_spec.rb:27:in `block (3 levels) in <top (required)>'

Finished in 4.23 seconds (files took 1.26 seconds to load)
26 examples, 8 failures

Failed examples:

rspec ./spec/account_integration_spec.rb:17 # Create Account can create an account
rspec ./spec/has_many_integration_spec.rb:28 # HasManyRelations can specify conditions and order
rspec ./spec/has_many_integration_spec.rb:37 # HasManyRelations can behave like an array
rspec ./spec/has_many_integration_spec.rb:42 # HasManyRelations can respond to functions on the Relation
rspec ./spec/subscribe_integration_spec.rb:41 # Subscribe Can successfully subscribe and amend using a new account
rspec ./spec/subscribe_integration_spec.rb:124 # Subscribe Can successfully subscribe and generate a bill preview and an invoice
rspec ./spec/subscribe_integration_spec.rb:228 # Subscribe Can successfully batch subscribe from a collection proxy of subscribe requests and generate an invoice for the first subscription
rspec ./spec/zobject_integration_spec.rb:13 # ZObject can be created, queried, updated, and destroyed

$

error loading wsdl 57.0+

Hey guys,

I looked around for others with this issue, but couldn't find anything. Attempting to load the zuora wsdl after 56.0 results in an error

https://apisandbox.zuora.com/apps/servlet/GenerateWsdl?version=57.0

active_zuora-2.1.2/lib/active_zuora/generator.rb:33:in `const_set': wrong constant name calculateRequest (NameError)

This is because there are 2 complexTypes defined in the 57.0 wsdl with names that are not valid ruby constants.

<complexType name="calculateRequest">
<sequence>
<element minOccurs="1" maxOccurs="1" name="chargeId" type="string"/>
</sequence>
</complexType>

<complexType name="calculateResult">
<sequence>
<element minOccurs="1" maxOccurs="1" name="Success" type="boolean"/>
<element minOccurs="1" maxOccurs="1" name="Size" nillable="true" type="int"/>
<element minOccurs="0" maxOccurs="unbounded" name="Error" nillable="true" type="zns:ChargeMetricsError"/>
<element minOccurs="0" maxOccurs="unbounded" name="ChargeMetrics" type="ons:ChargeMetrics"/>
</sequence>
</complexType>

A ruby constant must start with a capital letter. Capitalizing these type names in the wsdl fixes it, but I have no idea the ramifications of doing this. I will do my best to look further into it both with zuora and in the gem to see if there is a better work around that doesn't require modifying the wsdl.

Any help / feedback is appreciated.

Logging Mechanism

Hey,

I've just been poking around the code base, and it would be great if I could get a clarification on this piece of code

Am I right in saying that this mechanism will globally set the value of the HTTPI logger for all gems?

For instance, if there are 3 mechanisms using HTTPI which are currently set to log, and I then additionally add active_zuora with logging set to false, the existing mechanisms will no longer log?

Unknown Field type: date

I receive the following error multiple times when generating classes:
Unknown field type: date

Here is a snippet from object ProductRatePlan (wsdl 73.0)

I think these should fall under datetime.

Based on the code the change should be made in I think
https://github.com/sportngin/active_zuora/blob/master/lib/active_zuora/fields.rb#L103

But when I changed it and added a line stating date as the symbol it continued to complain about that field type after deploying the changed gem.

Did I miss somewhere else that it should be changed? I'm happy to make a PR to fix this I just can't find where I need to change it.

How do you override endpoints

Zuora requires different end points for sandbox vs. production. How do you over ride the endpoint with our needing to use a whole different wsdl?

Savon 2

Is there the idea to make it works with Savon 2?

I'm trying to do it but I got locked up on:

result = self.class.connection.request(:create) do |soap|
  soap.body do |xml|
    build_xml(xml, soap,
      ...

Ability to find by multiple IDs

I think would be a great idea to have the ability to find by an array of IDs in the same way that ActiveRecord behaves, we can save some SOAP request with this feature. Right now we can achieve this with:

Model.where(id: '<id>').or(id: '<id2>')...

I'm wondering if somebody has a different way to do that.

Is there a better way pulling subscription info?

Sorry if this is the wrong place to ask, but is there a better way than below of pulling subscription info? I'm hoping that there is an eager loading option that I'm missing.

Currently I'm doing this:
account = ActiveZuora::Account.where(account_number: "12323").first account.subscriptions.scope.where(status: "Active").first.rate_plans.*.rate_plan_charges
That ends up creating 3 SOAP requests. Is there a way of eager loading similar to the REST API?

Restricted Zuora Bank Transfer Account Number is included in PaymentMethod queries

When doing a select on PaymentMethod, the Zuora write-only field BankTransferAccountNumber is included in queries which is causing the query to fail.

Suggestion, these types of restricted fields should be configurable via config so we do not have to wait for GEM updates to fix them. At the moment we had to enumerate all the fields in our queries, not ideal but it works.

Error Population

Currently when asking a model for its errors, No result returned is being returned, instead of a list of known errors.

Example Scenario

  • A zuora account has been created with a missing state field
  • A further update is made to activate the account
Request Payload
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:zns="http://api.zuora.com/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:ins0="http://api.zuora.com/" xmlns:ins1="http://object.api.zuora.com/"
              xmlns:ins2="http://fault.api.zuora.com/">
  <env:Header>
    <SessionHeader>
      <session>
        ...
      </session>
    </SessionHeader>
  </env:Header>
  <env:Body>
    <ins0:update>
      <ins0:zObjects xsi:type="ins0:Account">
        <ins1:Id>Foo</ins1:Id>
        <ins1:Status>Active</ins1:Status>
      </ins0:zObjects>
    </ins0:update>
  </env:Body>
Response Payload
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <ns1:updateResponse xmlns:ns1="http://api.zuora.com/">
      <ns1:result>
        <ns1:Errors>
          <ns1:Code>MISSING_REQUIRED_VALUE</ns1:Code>
          <ns1:Message>Taxation Requirement: State is required for Sold To Contact if the country is United States or
            Canada.
          </ns1:Message>
        </ns1:Errors>
        <ns1:Success>false</ns1:Success>
      </ns1:result>
    </ns1:updateResponse>
  </soapenv:Body>
</soapenv:Envelope>

Problem

When asking model.errors.full_messages the result is ["No result returned."]

Expected

The error message Taxation Requirement: State is required for Sold To Contact if the country is United States or Canada should be present within `model.errors.

Investigation

The default error message seems to be populated here, as the results object does contain an id field, and is therefore not being populated correctly.

Within this context action is set to :update and results is set to

[
  {
    "errors": {
      "code": "MISSING_REQUIRED_VALUE",
      "message": "Taxation Requirement: State is required for Sold To Contact if the country is United States or Canada."
    },
    "success": false
  }
]

It would be great to add and handle this use edge-case :)

select includes non-selected fields

From the readme:

ActiveZuora::Account.select(:id, :name).where(:created_date => { "<" => Date.yesterday })

The resulting ActiveZuora::Account instances will include fields for all other possible ActiveZuora::Account, with a value of nil. This is unlike ActiveRecord, which omits any fields that are not specified in the select. These extra fields make it so that additional manipulation of the objects is necessary for some use cases, for example rendering to JSON.

Is this expected behavior, or is it a potential area for improvement?

Figure out request mocking for tests for zuora api

I'd like to remove the dependency on the zuora api to run integration tests. We could use something like VCR that would just record a hard run with an active zuora api connection and then we wouldn't need it all the time, just update it periodically.

invalid field for query when trying to find a payment.

> ActiveZuora::Payment.find("payment id")
> Savon::SOAP::Fault: (fns:INVALID_FIELD) invalid field for query: Payment.invoicepaymentdata: select Id, AccountId, AccountingCode, Amount, AppliedCreditBalanceAmount, AuthTransactionId, BankIdentification
Number, CancelledOn, Comment, CreatedById, CreatedDate, EffectiveDate, Gateway, GatewayOrderId, GatewayResponse, GatewayResponseCode, GatewayState, InvoicePaymentData, MarkedForSubmissionOn, PaymentMethod
Id, PaymentMethodSnapshotId, PaymentNumber, ReferenceId, RefundAmount, SecondPaymentReferenceId, SettledOn, SoftDescriptor, SoftDescriptorPhone, Status, SubmittedOn, TransferredToAccounting, Type, Updated
ById, UpdatedDate from Payment where Id = 'payment id'
from /var/bundle/ruby/2.0.0/gems/savon-1.2.0/lib/savon/soap/response.rb:107:in `raise_errors'

using zuora.a.65.0.wsdl
cc @IamDavidovich

Account model may be missing contact relations

Seems like instances of ActiveZuora::Account do not have relations to their bill-to and sold-to contacts.

The following works:

ActiveZuora::Account.find('valid_account_id').contacts
ActiveZuora::Account.find('valid_account_id').bill_to_id
ActiveZuora::Account.find('valid_account_id').sold_to_id

But the following relations seem to be missing:

ActiveZuora::Account.find('valid_account_id').bill_to
ActiveZuora::Account.find('valid_account_id').sold_to

Thanks!

Support for update only fields

In the WSDL version 40+ there is a field on the Invoice object "RegenerateInvoicePDF" which is only used for the update method - when selecting the field it raises an error.

invalid field for query: Invoice.RegenerateInvoicePDF

the work around is to use the select method and exclude the field from the parameters.

Any suggestions on where to start to support this type of field that cannot be queried?

prevent tampering with timestamps

This has caused me a great deal of pain in the last week (was thinking it was a limitation on the Zuora side):

https://github.com/sportngin/active_zuora/blob/master/lib/active_zuora/fields/date_time_field.rb#L11-14

It should just use %Y-%m-%dT%H:%M:%S-08:00. This will add the 00:00:00 Timestamp even if one doesn't exist, but at least it won't overwrite timestamps if they're provided.

Also, usage startdatetime and enddatetime are good examples of user-set attributes that are not just dates, but a full timestamp.

I can submit a patch, but there are no tests for that stuff, so I will spend some time over the weekend adding a test for that, hopefullly.

Generate a preview for future Invoice - BillingPreview()

Hello,

I have been trying to test the BillingPreview () call and seems like there is no support in active_zuora. Are there any plans to include support for the same ?

Currently these seem to be the only options for anything related to BillingPreview
[:BillingPreviewRequest, :BillingPreviewResult, :BillingPreviewRun]

Alternatively, I tried to use the BillingPreviewRun instead

2.2.0 :016 > bpr = ActiveZuora::BillingPreviewRun.new ({"target_date": "2015-05-31"})

=> #<ActiveZuora::BillingPreviewRun:0x007fc1412f2880 @id=nil, @Batch=nil, @charge_type_to_exclude=nil, @created_by_id=nil, @created_date=nil, @end_date=nil, @error_message=nil, @including_evergreen_subscription=nil, @result_file_url=nil, @run_number=nil, @start_date=nil, @status=nil, @succeeded_accounts=nil, @target_date=Sun, 31 May 2015 00:00:00 +0000, @total_accounts=nil, @updated_by_id=nil, @updated_date=nil, @changed_attributes={"target_date"=>nil}>

But ended up getting this...

2.2.0 :018 > bpr.create
NoMethodError: private method `create' called for #ActiveZuora::BillingPreviewRun:0x007fc1412f2880

Appreciate any help or feedback on this issue. Thanks!

Saving multiple usage instances at once

Hi, I was wondering whether it is possible somehow to push multiple usage entries to Zuora at once, with a single API call? At the moment I have an application that makes three API calls to push three usage entries, but I would like to do this with a single API call if possible.

Thanks!

Support For Batched Creates

It doesn't appear that this gem supports batched creates. Am I correct in this assumption? The update function in the persistance class looks like it does batch updates but I don't see a way to do batched creates.

Please let me know if I'm missing this functionality, otherwise I may look at adding this functionality if we go with this gem. Thanks.

Rails 5.1

I would like to use this gem on a rails 5.1 branch. Based on a local branch I believe that updating the dependencies for activesupport and activemodel should suffice.

Thread Safety on README

It doesn't look like the Thread Safety is an issue anymore with the newer version of Savon (1.2.0) being used, but the repo README says otherwise. Anyone confirm this?

REST integration

Hey;

I'm a massive fan of active_zuora, in particular the API abstraction that it offers.

Now that Zuora supporst 100% REST; Are there any plans to support making REST calls instead of SOAP, but still use the same active_zuora API?

Thanks ๐Ÿ‘

Update rubygems homepage link

The rubygems.org page still points to 'tstmedia/active_zuora'. It would be nice to know what the latest repo is in one hop rather than 2. :)

Thanks

Error when querying PaymentMethodSnapshot object

Z::PaymentMethodSnapshot.last
....
NoMethodError: undefined method `created_date' for #<Z::PaymentMethodSnapshot:0x007ff5d49ee298>
from /Users/ruben/.rvm/gems/ruby-2.2.4/gems/activemodel-4.2.6/lib/active_model/attribute_methods.rb:433:in `method_missing'

The error is raised because the code assumes that all objects have the CreatedDate field:

@order_attribute, @order_direction = :created_date, :asc

CHANGELOG

We where just updating our bundle and figured there was an update on this gem.
Unfortunately the CHANGELOG seems to be abandoned. Is there a specific reason for this?

Different Class nesting - Specifying target module

The readme currently states -

By default, it will generate the classes inside the ActiveZuora module. But you can specify a different nesting if you'd like.

    ActiveZuora.generate_classes :under => SomeOtherModule

From inspecting the code, the symbol appears to be inside, rather than under

Error when querying for multiple invoices

I have an error popping up any time I request more than one invoice:

> ActiveZuora::Account.invoices.all
Savon::SOAP::Fault: (fns:INVALID_VALUE) Can only query one invoice body at a time.: select Id, AccountId, AdjustmentAmount, Amount, AmountWithoutTax, Balance, Body, Comments, CreatedById, CreatedDate, CreditBalanceAdjustmentAmount, DueDate, IncludesOneTime, IncludesRecurring, IncludesUsage, InvoiceDate, InvoiceNumber, LastEmailSentDate, PaymentAmount, PostedBy, PostedDate, RefundAmount, Status, TargetDate, TaxAmount, TaxExemptAmount, TransferredToAccounting, UpdatedById, UpdatedDate from Invoice where AccountId = 'account_id_was_here'

It's fine if I limit it in a way that I'm only requesting a single invoice:

> ActiveZuora::Invoice.where(invoice_number: 'INV00000001').first
=> #<ActiveZuora::Invoice:0x007fbbee188088
 @account_id="account_id_was_here",
  ...

Is there a way of fixing this without having to manually implement the Invoice model?

Add RevenueRecognitionRuleName to excluded fields for RatePlanCharge

Hi guys,

Our project has recently needed to upgrade the WSDL to 64.0 and ran into this:

invalid field for query: RatePlanCharge.RevenueRecognitionRuleName: select Id, AccountingCode, ApplyDiscountTo, BillCycleDay, BillCycleType, BillingPeriod, BillingPeriodAlignment, ChargedThroughDate, ChargeModel, ChargeNumber, ChargeType, CreatedById, CreatedDate, Description, DiscountLevel, DMRC, DTCV, EffectiveEndDate, EffectiveStartDate, IsLastSegment, MRR, Name, NumberOfPeriods, OriginalId, OverageCalculationOption, OverageUnusedUnitsCreditOption, Price, PriceChangeOption, PriceIncreasePercentage, ProcessedThroughDate, ProductRatePlanChargeId, Quantity, RatePlanId, RevenueRecognitionRuleName, RevRecCode, RevRecTriggerCondition, Segment, SpecificBillingPeriod, TCV, TriggerDate, TriggerEvent, UnusedUnitsCreditRates, UOM, UpdatedById, UpdatedDate, UpToPeriods, UsageRecordRatingOption, UseDiscountSpecificAccountingCode, Version from RatePlanCharge where RatePlanId = '...'

I got the following response from Zuora support:

The field "RevenueRecognitionRuleName" is a field introduced in the WSDL if the feature Z-Finance is enabled in your environment.

As you've noticed, this field is not supported when executing a query() call against the RatePlanCharge object as there limitations which prevents this field to be exposed as part of the RatePlanCharge query() call.

Although this field does not support the query() call, it has been made available as part of the RatePlanCharge object as this supports the update() call to modify the current value given that the subscription owning the RatePlan and RatePlanCharge objects is still in a 'Draft' status. Furthermore, the subscribe() call creating a new subscription, RatePlan, and RatePlanCharge object supports passing the field "RevenueRecognitionRuleName" to override the default value set at the ProductRatePlanCharge object.

So to work around I've monkey patched the generated RatePlanCharge object. Would it be possible for you to add this field to the list of excluded query fields for that object?

Thanks,
Scott Payne

Cannot create ProductRatePlanChargeTier independently

ActiveZuora::ProductRatePlanChargeTier.create!
=> Savon::SOAP::Fault: (fns:INVALID_TYPE) invalid type for create:ProductRatePlanChargeTier

Can I only create ProductRatePlanChargeTiers when creating a ProductRatePlanCharge?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.