xeroizer 2.16.4 → 2.16.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +20 -1
- data/lib/xeroizer.rb +2 -1
- data/lib/xeroizer/generic_application.rb +3 -1
- data/lib/xeroizer/http.rb +6 -0
- data/lib/xeroizer/models/accounts_payable.rb +13 -0
- data/lib/xeroizer/models/accounts_receivable.rb +13 -0
- data/lib/xeroizer/models/balances.rb +16 -0
- data/lib/xeroizer/models/batch_payments.rb +14 -0
- data/lib/xeroizer/models/bills.rb +13 -0
- data/lib/xeroizer/models/contact.rb +10 -3
- data/lib/xeroizer/models/payment_terms.rb +16 -0
- data/lib/xeroizer/models/purchase_order.rb +49 -0
- data/lib/xeroizer/models/sales.rb +13 -0
- data/lib/xeroizer/oauth.rb +22 -21
- data/lib/xeroizer/record/base_model.rb +1 -1
- data/lib/xeroizer/record/record_association_helper.rb +2 -0
- data/lib/xeroizer/report/factory.rb +1 -1
- data/lib/xeroizer/version.rb +1 -1
- data/test/stub_responses/contact.xml +25 -11
- data/test/stub_responses/contact_with_details.xml +79 -0
- data/test/stub_responses/nonce_used +1 -0
- data/test/unit/models/bank_transaction_test.rb +2 -2
- data/test/unit/models/contact_test.rb +85 -11
- data/test/unit/oauth_test.rb +20 -1
- data/test/unit/report_test.rb +12 -1
- metadata +14 -4
- data/lib/big_decimal_to_s.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 661b00281b09048f7c58f3bc0e4c12d3401fc9c3
|
4
|
+
data.tar.gz: 79db1f4fa930e1deb41f78fd0cee48ee6e30ab95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5dec38c448515e18f9aad030a0ae05bcd7504133474fcc8b52d06be00947db73556416414bb528483810d894a97785d862540b4d7a4cdd948632b99c5ef0abdf
|
7
|
+
data.tar.gz: 091ef6309c0a17f85976b1135eaca233de6b3e7031b972bfbdc14c81b9016c67177f6fdf1ebdca9694047aba232a5f5c6d7e95cf2f1f1f49c13c3cab7b139156
|
data/README.md
CHANGED
@@ -531,7 +531,7 @@ are welcome).
|
|
531
531
|
Reports are accessed like the following example:
|
532
532
|
|
533
533
|
```ruby
|
534
|
-
trial_balance = xero.TrialBalance.get(:date =>
|
534
|
+
trial_balance = xero.TrialBalance.get(:date => DateTime.new(2011,3,21))
|
535
535
|
|
536
536
|
# Array containing report headings.
|
537
537
|
trial_balance.header.cells.map { | cell | cell.value }
|
@@ -588,6 +588,25 @@ client = Xeroizer::PublicApplication.new(YOUR_OAUTH_CONSUMER_KEY,
|
|
588
588
|
:rate_limit_sleep => 2)
|
589
589
|
```
|
590
590
|
|
591
|
+
Xero API Nonce Used
|
592
|
+
-------------------
|
593
|
+
|
594
|
+
The Xero API seems to reject requests due to conflicts on occasion.
|
595
|
+
|
596
|
+
By default, the library will raise a `Xeroizer::OAuth::NonceUsed`
|
597
|
+
exception when one of these limits is exceeded.
|
598
|
+
|
599
|
+
If required, the library can handle these exceptions internally by sleeping 1 second and then repeating the last request.
|
600
|
+
You can set this option when initializing an application:
|
601
|
+
|
602
|
+
```ruby
|
603
|
+
# Sleep for 2 seconds every time the rate limit is exceeded.
|
604
|
+
client = Xeroizer::PublicApplication.new(YOUR_OAUTH_CONSUMER_KEY,
|
605
|
+
YOUR_OAUTH_CONSUMER_SECRET,
|
606
|
+
:nonce_used_max_attempts => 3)
|
607
|
+
```
|
608
|
+
|
609
|
+
|
591
610
|
Logging
|
592
611
|
---------------
|
593
612
|
|
data/lib/xeroizer.rb
CHANGED
@@ -3,6 +3,7 @@ require 'date'
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'active_support/inflector'
|
5
5
|
require "active_support/core_ext/array"
|
6
|
+
require "active_support/core_ext/big_decimal/conversions"
|
6
7
|
require 'oauth'
|
7
8
|
require 'oauth/signature/rsa/sha1'
|
8
9
|
require 'nokogiri'
|
@@ -13,7 +14,6 @@ require 'cgi'
|
|
13
14
|
|
14
15
|
$: << File.expand_path(File.dirname(__FILE__))
|
15
16
|
|
16
|
-
require 'big_decimal_to_s'
|
17
17
|
require 'class_level_inheritable_attributes'
|
18
18
|
require 'xeroizer/oauth'
|
19
19
|
require 'xeroizer/http_encoding_helper'
|
@@ -51,6 +51,7 @@ require 'xeroizer/models/organisation'
|
|
51
51
|
require 'xeroizer/models/payment'
|
52
52
|
require 'xeroizer/models/prepayment'
|
53
53
|
require 'xeroizer/models/phone'
|
54
|
+
require 'xeroizer/models/purchase_order'
|
54
55
|
require 'xeroizer/models/receipt'
|
55
56
|
require 'xeroizer/models/repeating_invoice'
|
56
57
|
require 'xeroizer/models/schedule'
|
@@ -7,7 +7,7 @@ module Xeroizer
|
|
7
7
|
extend Record::ApplicationHelper
|
8
8
|
|
9
9
|
attr_reader :client, :xero_url, :logger, :rate_limit_sleep, :rate_limit_max_attempts,
|
10
|
-
:default_headers, :unitdp, :before_request, :after_request
|
10
|
+
:default_headers, :unitdp, :before_request, :after_request, :nonce_used_max_attempts
|
11
11
|
|
12
12
|
extend Forwardable
|
13
13
|
def_delegators :client, :access_token
|
@@ -29,6 +29,7 @@ module Xeroizer
|
|
29
29
|
record :Organisation
|
30
30
|
record :Payment
|
31
31
|
record :Prepayment
|
32
|
+
record :PurchaseOrder
|
32
33
|
record :Receipt
|
33
34
|
record :RepeatingInvoice
|
34
35
|
record :Schedule
|
@@ -58,6 +59,7 @@ module Xeroizer
|
|
58
59
|
@xero_url = options[:xero_url] || "https://api.xero.com/api.xro/2.0"
|
59
60
|
@rate_limit_sleep = options[:rate_limit_sleep] || false
|
60
61
|
@rate_limit_max_attempts = options[:rate_limit_max_attempts] || 5
|
62
|
+
@nonce_used_max_attempts = options[:nonce_used_max_attempts] || 1
|
61
63
|
@default_headers = options[:default_headers] || {}
|
62
64
|
@before_request = options.delete(:before_request)
|
63
65
|
@after_request = options.delete(:after_request)
|
data/lib/xeroizer/http.rb
CHANGED
@@ -121,6 +121,11 @@ module Xeroizer
|
|
121
121
|
else
|
122
122
|
handle_unknown_response_error!(response)
|
123
123
|
end
|
124
|
+
rescue Xeroizer::OAuth::NonceUsed => exception
|
125
|
+
raise if attempts > nonce_used_max_attempts
|
126
|
+
logger.info("Nonce used: " + exception.to_s) if self.logger
|
127
|
+
sleep_for(1)
|
128
|
+
retry
|
124
129
|
rescue Xeroizer::OAuth::RateLimitExceeded
|
125
130
|
if self.rate_limit_sleep
|
126
131
|
raise if attempts > rate_limit_max_attempts
|
@@ -157,6 +162,7 @@ module Xeroizer
|
|
157
162
|
when "token_rejected" then raise OAuth::TokenInvalid.new(description)
|
158
163
|
when "rate limit exceeded" then raise OAuth::RateLimitExceeded.new(description)
|
159
164
|
when "consumer_key_unknown" then raise OAuth::ConsumerKeyUnknown.new(description)
|
165
|
+
when "nonce_used" then raise OAuth::NonceUsed.new(description)
|
160
166
|
else raise OAuth::UnknownError.new(problem + ':' + description)
|
161
167
|
end
|
162
168
|
else
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "xeroizer/models/accounts_receivable"
|
2
|
+
require "xeroizer/models/accounts_payable"
|
3
|
+
|
4
|
+
module Xeroizer
|
5
|
+
module Record
|
6
|
+
|
7
|
+
class BalancesModel < BaseModel
|
8
|
+
set_permissions :read
|
9
|
+
end
|
10
|
+
|
11
|
+
class Balances < Base
|
12
|
+
has_one :accounts_receivable
|
13
|
+
has_one :accounts_payable
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
require "xeroizer/models/contact_person"
|
2
|
+
require "xeroizer/models/balances"
|
3
|
+
require "xeroizer/models/batch_payments"
|
4
|
+
require "xeroizer/models/payment_terms"
|
2
5
|
|
3
6
|
module Xeroizer
|
4
7
|
module Record
|
@@ -36,12 +39,12 @@ module Xeroizer
|
|
36
39
|
string :skype_user_name
|
37
40
|
string :contact_groups
|
38
41
|
string :default_currency
|
39
|
-
string :purchases_default_account_code
|
40
|
-
string :sales_default_account_code
|
42
|
+
string :purchases_default_account_code
|
43
|
+
string :sales_default_account_code
|
41
44
|
datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC'
|
42
45
|
boolean :is_supplier
|
43
46
|
boolean :is_customer
|
44
|
-
|
47
|
+
|
45
48
|
has_many :addresses, :list_complete => true
|
46
49
|
has_many :phones, :list_complete => true
|
47
50
|
has_many :contact_groups
|
@@ -50,6 +53,10 @@ module Xeroizer
|
|
50
53
|
has_many :sales_tracking_categories, :model_name => 'ContactSalesTrackingCategory'
|
51
54
|
has_many :purchases_tracking_categories, :model_name => 'ContactPurchasesTrackingCategory'
|
52
55
|
|
56
|
+
has_one :balances ,:model_name => 'Balances', :list_complete => true
|
57
|
+
has_one :batch_payments ,:model_name => 'BatchPayments', :list_complete => true
|
58
|
+
has_one :payment_terms ,:model_name => 'PaymentTerms', :list_complete => true
|
59
|
+
|
53
60
|
validates_presence_of :name, :unless => Proc.new { | contact | contact.contact_id.present?}
|
54
61
|
validates_inclusion_of :contact_status, :in => CONTACT_STATUS.keys, :allow_blanks => true
|
55
62
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "xeroizer/models/bills"
|
2
|
+
require "xeroizer/models/sales"
|
3
|
+
|
4
|
+
module Xeroizer
|
5
|
+
module Record
|
6
|
+
|
7
|
+
class PaymentTermsModel < BaseModel
|
8
|
+
set_permissions :read
|
9
|
+
end
|
10
|
+
|
11
|
+
class PaymentTerms < Base
|
12
|
+
has_one :bills, :model_name => 'Bills'
|
13
|
+
has_one :sales, :model_name => 'Sales'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "xeroizer/models/attachment"
|
2
|
+
|
3
|
+
module Xeroizer
|
4
|
+
module Record
|
5
|
+
|
6
|
+
class PurchaseOrderModel < BaseModel
|
7
|
+
|
8
|
+
set_permissions :read, :write, :update
|
9
|
+
|
10
|
+
include AttachmentModel::Extensions
|
11
|
+
end
|
12
|
+
|
13
|
+
class PurchaseOrder < Base
|
14
|
+
include Attachment::Extensions
|
15
|
+
|
16
|
+
set_primary_key :purchase_order_id
|
17
|
+
set_possible_primary_keys :purchase_order_id
|
18
|
+
|
19
|
+
guid :purchase_order_id
|
20
|
+
string :purchase_order_number
|
21
|
+
string :date_string
|
22
|
+
date :date
|
23
|
+
string :delivery_date_string
|
24
|
+
date :delivery_date
|
25
|
+
string :delivery_address
|
26
|
+
string :attention_to
|
27
|
+
string :telephone
|
28
|
+
string :delivery_instructions
|
29
|
+
boolean :has_errors
|
30
|
+
boolean :is_discounted
|
31
|
+
string :reference
|
32
|
+
string :type
|
33
|
+
string :currency_rate
|
34
|
+
string :currency_code
|
35
|
+
guid :branding_theme_id
|
36
|
+
string :status
|
37
|
+
string :line_amount_types
|
38
|
+
string :sub_total
|
39
|
+
string :total_tax
|
40
|
+
string :total
|
41
|
+
date :updated_date_UTC
|
42
|
+
boolean :has_attachments
|
43
|
+
|
44
|
+
has_many :line_items
|
45
|
+
belongs_to :contact, :model_name => 'Contact'
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
data/lib/xeroizer/oauth.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Permission to use, copy, modify, and/or distribute this software for any
|
4
4
|
# purpose with or without fee is hereby granted, provided that the above
|
5
5
|
# copyright notice and this permission notice appear in all copies.
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
8
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
9
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
@@ -13,21 +13,22 @@
|
|
13
13
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
14
|
|
15
15
|
module Xeroizer
|
16
|
-
|
17
|
-
# Shamelessly taken from the XeroGateway library by Tim Connor which is shamelessly
|
16
|
+
|
17
|
+
# Shamelessly taken from the XeroGateway library by Tim Connor which is shamelessly
|
18
18
|
# based on the Twitter Gem's OAuth implementation by John Nunemaker
|
19
19
|
# Thanks!
|
20
|
-
#
|
20
|
+
#
|
21
21
|
# http://github.com/tlconnor/xero_gateway
|
22
22
|
# http://twitter.rubyforge.org/
|
23
23
|
# http://github.com/jnunemaker/twitter/
|
24
|
-
|
24
|
+
|
25
25
|
class OAuth
|
26
|
-
|
26
|
+
|
27
27
|
class TokenExpired < StandardError; end
|
28
28
|
class TokenInvalid < StandardError; end
|
29
29
|
class RateLimitExceeded < StandardError; end
|
30
30
|
class ConsumerKeyUnknown < StandardError; end
|
31
|
+
class NonceUsed < StandardError; end
|
31
32
|
class UnknownError < StandardError; end
|
32
33
|
|
33
34
|
unless defined? XERO_CONSUMER_OPTIONS
|
@@ -36,20 +37,20 @@ module Xeroizer
|
|
36
37
|
:request_token_path => "/oauth/RequestToken",
|
37
38
|
:access_token_path => "/oauth/AccessToken",
|
38
39
|
:authorize_path => "/oauth/Authorize",
|
39
|
-
|
40
|
+
#:ca_file => File.expand_path(File.join(File.dirname(__FILE__), 'ca-certificates.crt'))
|
40
41
|
}.freeze
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
# Mixin real OAuth methods for consumer.
|
44
45
|
extend Forwardable
|
45
46
|
def_delegators :access_token, :get, :post, :put, :delete
|
46
|
-
|
47
|
+
|
47
48
|
# @attr_reader [String] ctoken consumer key/token from application developer (found at http://api.xero.com for your application).
|
48
49
|
# @attr_reader [String] csecret consumer secret from application developer (found at http://api.xero.com for your application).
|
49
50
|
# @attr_reader [Time] expires_at time the AccessToken expires if using the PartnerApplication mode (usually 30 minutes for Xero).
|
50
51
|
# @attr_reader [Time] authorization_expires_at time the session expires if using the ParnterApplication mode (usually 365 days for Xero).
|
51
52
|
attr_reader :ctoken, :csecret, :consumer_options, :expires_at, :authorization_expires_at
|
52
|
-
|
53
|
+
|
53
54
|
# @attr_reader [String] session_handle session handle used to renew AccessToken if using the PartnerApplication mode.
|
54
55
|
# @attr_writer [String] session_handle session handle used to renew AccessToken if using the PartnerApplication mode.
|
55
56
|
attr_accessor :session_handle
|
@@ -72,35 +73,35 @@ module Xeroizer
|
|
72
73
|
@ctoken, @csecret = ctoken, csecret
|
73
74
|
@consumer_options = XERO_CONSUMER_OPTIONS.merge(options)
|
74
75
|
end
|
75
|
-
|
76
|
+
|
76
77
|
# OAuth consumer creator.
|
77
|
-
#
|
78
|
+
#
|
78
79
|
# @return [OAuth::Consumer] consumer object for GET/POST/PUT methods.
|
79
80
|
def consumer
|
80
81
|
create_consumer
|
81
82
|
end
|
82
|
-
|
83
|
-
# RequestToken for PUBLIC/PARTNER authorisation
|
83
|
+
|
84
|
+
# RequestToken for PUBLIC/PARTNER authorisation
|
84
85
|
# (used to redirect to Xero for authentication).
|
85
86
|
#
|
86
87
|
# @option params [String] :oauth_callback URL to redirect user to when they have authenticated your application with Xero. If not specified, the user will be shown an authorisation code on the screen that they need to get into your application.
|
87
88
|
def request_token(params = {})
|
88
89
|
consumer.get_request_token(params, {}, @consumer_options[:default_headers])
|
89
90
|
end
|
90
|
-
|
91
|
+
|
91
92
|
# Create an AccessToken from a PUBLIC/PARTNER authorisation.
|
92
93
|
def authorize_from_request(rtoken, rsecret, params = {})
|
93
94
|
request_token = ::OAuth::RequestToken.new(consumer, rtoken, rsecret)
|
94
95
|
access_token = request_token.get_access_token(params, {}, @consumer_options[:default_headers])
|
95
96
|
update_attributes_from_token(access_token)
|
96
97
|
end
|
97
|
-
|
98
|
+
|
98
99
|
# AccessToken created from authorize_from_access method.
|
99
100
|
def access_token
|
100
101
|
::OAuth::AccessToken.new(consumer, @atoken, @asecret)
|
101
102
|
end
|
102
|
-
|
103
|
-
# Used for PRIVATE applications where the AccessToken uses the
|
103
|
+
|
104
|
+
# Used for PRIVATE applications where the AccessToken uses the
|
104
105
|
# token/secret from Xero which would normally be used in the request.
|
105
106
|
# No request authorisation necessary.
|
106
107
|
#
|
@@ -109,13 +110,13 @@ module Xeroizer
|
|
109
110
|
def authorize_from_access(atoken, asecret)
|
110
111
|
@atoken, @asecret = atoken, asecret
|
111
112
|
end
|
112
|
-
|
113
|
+
|
113
114
|
# Renew an access token from a previously authorised token for a
|
114
115
|
# PARTNER application.
|
115
116
|
def renew_access_token(atoken = nil, asecret = nil, session_handle = nil)
|
116
117
|
old_token = ::OAuth::RequestToken.new(consumer, atoken || @atoken, asecret || @asecret)
|
117
118
|
access_token = old_token.get_access_token({
|
118
|
-
:oauth_session_handle => (session_handle || @session_handle),
|
119
|
+
:oauth_session_handle => (session_handle || @session_handle),
|
119
120
|
:token => old_token
|
120
121
|
}, {}, @consumer_options[:default_headers])
|
121
122
|
update_attributes_from_token(access_token)
|
data/lib/xeroizer/version.rb
CHANGED
@@ -5,36 +5,50 @@
|
|
5
5
|
<DateTimeUTC>2010-12-20T04:13:44.7828584Z</DateTimeUTC>
|
6
6
|
<Contacts>
|
7
7
|
<Contact>
|
8
|
-
<ContactID>
|
8
|
+
<ContactID>bd2270c3-8706-4c11-9cfb-000b551c3f51</ContactID>
|
9
9
|
<ContactStatus>ACTIVE</ContactStatus>
|
10
|
-
<Name>
|
11
|
-
<FirstName>
|
12
|
-
<LastName>
|
10
|
+
<Name>ABC Limited</Name>
|
11
|
+
<FirstName>Andrea</FirstName>
|
12
|
+
<LastName>Dutchess</LastName>
|
13
|
+
<EmailAddress>a.dutchess@abclimited.com</EmailAddress>
|
14
|
+
<SkypeUserName>skype.dutchess@abclimited.com</SkypeUserName>
|
15
|
+
<BankAccountDetails>skype.dutchess@abclimited.com</BankAccountDetails>
|
16
|
+
<TaxNumber>skype.dutchess@abclimited.com</TaxNumber>
|
17
|
+
<AccountsReceivableTaxType>INPUT2</AccountsReceivableTaxType>
|
18
|
+
<AccountsPayableTaxType>OUTPUT2</AccountsPayableTaxType>
|
13
19
|
<Addresses>
|
14
20
|
<Address>
|
15
21
|
<AddressType>POBOX</AddressType>
|
16
|
-
|
22
|
+
<AddressLine1>P O Box 123</AddressLine1>
|
23
|
+
<City>Wellington</City>
|
24
|
+
<PostalCode>6011</PostalCode>
|
25
|
+
<AttentionTo>Andrea</AttentionTo>
|
26
|
+
</Address>
|
17
27
|
<Address>
|
18
28
|
<AddressType>STREET</AddressType>
|
19
29
|
</Address>
|
20
30
|
</Addresses>
|
21
31
|
<Phones>
|
22
32
|
<Phone>
|
23
|
-
<PhoneType>
|
33
|
+
<PhoneType>DEFAULT</PhoneType>
|
34
|
+
<PhoneNumber>1111111</PhoneNumber>
|
35
|
+
<PhoneAreaCode>04</PhoneAreaCode>
|
36
|
+
<PhoneCountryCode>64</PhoneCountryCode>
|
24
37
|
</Phone>
|
25
38
|
<Phone>
|
26
|
-
<PhoneType>
|
39
|
+
<PhoneType>FAX</PhoneType>
|
27
40
|
</Phone>
|
28
41
|
<Phone>
|
29
42
|
<PhoneType>MOBILE</PhoneType>
|
30
43
|
</Phone>
|
31
44
|
<Phone>
|
32
|
-
<PhoneType>
|
45
|
+
<PhoneType>DDI</PhoneType>
|
33
46
|
</Phone>
|
34
47
|
</Phones>
|
35
|
-
<UpdatedDateUTC>
|
48
|
+
<UpdatedDateUTC>2009-05-14T01:44:26.747</UpdatedDateUTC>
|
36
49
|
<IsSupplier>false</IsSupplier>
|
37
|
-
<IsCustomer>
|
50
|
+
<IsCustomer>true</IsCustomer>
|
51
|
+
<DefaultCurrency>NZD</DefaultCurrency>
|
38
52
|
</Contact>
|
39
53
|
</Contacts>
|
40
|
-
</Response>
|
54
|
+
</Response>
|
@@ -0,0 +1,79 @@
|
|
1
|
+
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
2
|
+
<Id>1238b00c-2fdd-4a8a-9b84-82cfe78ff34a</Id>
|
3
|
+
<Status>OK</Status>
|
4
|
+
<ProviderName>Test Provider Name</ProviderName>
|
5
|
+
<DateTimeUTC>2010-12-20T04:13:44.7828584Z</DateTimeUTC>
|
6
|
+
<Contacts>
|
7
|
+
<Contact>
|
8
|
+
<ContactID>bd2270c3-8706-4c11-9cfb-000b551c3f51</ContactID>
|
9
|
+
<ContactStatus>ACTIVE</ContactStatus>
|
10
|
+
<Name>ABC Limited</Name>
|
11
|
+
<FirstName>Andrea</FirstName>
|
12
|
+
<LastName>Dutchess</LastName>
|
13
|
+
<EmailAddress>a.dutchess@abclimited.com</EmailAddress>
|
14
|
+
<SkypeUserName>skype.dutchess@abclimited.com</SkypeUserName>
|
15
|
+
<BankAccountDetails>skype.dutchess@abclimited.com</BankAccountDetails>
|
16
|
+
<TaxNumber>skype.dutchess@abclimited.com</TaxNumber>
|
17
|
+
<AccountsReceivableTaxType>INPUT2</AccountsReceivableTaxType>
|
18
|
+
<AccountsPayableTaxType>OUTPUT2</AccountsPayableTaxType>
|
19
|
+
<Addresses>
|
20
|
+
<Address>
|
21
|
+
<AddressType>POBOX</AddressType>
|
22
|
+
<AddressLine1>P O Box 123</AddressLine1>
|
23
|
+
<City>Wellington</City>
|
24
|
+
<PostalCode>6011</PostalCode>
|
25
|
+
<AttentionTo>Andrea</AttentionTo>
|
26
|
+
</Address>
|
27
|
+
<Address>
|
28
|
+
<AddressType>STREET</AddressType>
|
29
|
+
</Address>
|
30
|
+
</Addresses>
|
31
|
+
<Phones>
|
32
|
+
<Phone>
|
33
|
+
<PhoneType>DEFAULT</PhoneType>
|
34
|
+
<PhoneNumber>1111111</PhoneNumber>
|
35
|
+
<PhoneAreaCode>04</PhoneAreaCode>
|
36
|
+
<PhoneCountryCode>64</PhoneCountryCode>
|
37
|
+
</Phone>
|
38
|
+
<Phone>
|
39
|
+
<PhoneType>FAX</PhoneType>
|
40
|
+
</Phone>
|
41
|
+
<Phone>
|
42
|
+
<PhoneType>MOBILE</PhoneType>
|
43
|
+
</Phone>
|
44
|
+
<Phone>
|
45
|
+
<PhoneType>DDI</PhoneType>
|
46
|
+
</Phone>
|
47
|
+
</Phones>
|
48
|
+
<UpdatedDateUTC>2009-05-14T01:44:26.747</UpdatedDateUTC>
|
49
|
+
<IsSupplier>false</IsSupplier>
|
50
|
+
<IsCustomer>true</IsCustomer>
|
51
|
+
<DefaultCurrency>NZD</DefaultCurrency>
|
52
|
+
<Balances>
|
53
|
+
<AccountsReceivable>
|
54
|
+
<Outstanding>849.50</Outstanding>
|
55
|
+
<Overdue>910.00</Overdue>
|
56
|
+
</AccountsReceivable>
|
57
|
+
<AccountsPayable>
|
58
|
+
<Outstanding>0.00</Outstanding>
|
59
|
+
<Overdue>0.00</Overdue>
|
60
|
+
</AccountsPayable>
|
61
|
+
</Balances>
|
62
|
+
<BatchPayments>
|
63
|
+
<BankAccountNumber>123456</BankAccountNumber>
|
64
|
+
<BankAccountName>bank account</BankAccountName>
|
65
|
+
<Details>details</Details>
|
66
|
+
</BatchPayments>
|
67
|
+
<PaymentTerms>
|
68
|
+
<Bills>
|
69
|
+
<Day>4</Day>
|
70
|
+
<Type>OFFOLLOWINGMONTH</Type>
|
71
|
+
</Bills>
|
72
|
+
<Sales>
|
73
|
+
<Day>2</Day>
|
74
|
+
<Type>OFFOLLOWINGMONTH</Type>
|
75
|
+
</Sales>
|
76
|
+
</PaymentTerms>
|
77
|
+
</Contact>
|
78
|
+
</Contacts>
|
79
|
+
</Response>
|
@@ -0,0 +1 @@
|
|
1
|
+
oauth_problem=nonce_used&oauth_problem_advice=The%20nonce%20value%20%22potatocakes%22%20has%20already%20been%20used%20
|
@@ -6,8 +6,8 @@ class BankTransactionTest < Test::Unit::TestCase
|
|
6
6
|
def setup
|
7
7
|
|
8
8
|
the_line_items = [
|
9
|
-
LineItem.build({:quantity => 1, :
|
10
|
-
LineItem.build({:quantity => 1, :
|
9
|
+
LineItem.build({:quantity => 1, :unit_amount => 1.00, :tax_amount => 0.50}, nil),
|
10
|
+
LineItem.build({:quantity => 1, :unit_amount => 1.00, :tax_amount => 0.50}, nil)
|
11
11
|
]
|
12
12
|
|
13
13
|
@the_bank_transaction = BankTransaction.new(nil)
|
@@ -2,23 +2,54 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class ContactTest < Test::Unit::TestCase
|
4
4
|
include TestHelper
|
5
|
-
|
5
|
+
|
6
6
|
def setup
|
7
7
|
@client = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET)
|
8
|
-
@contact = @client.Contact.build
|
9
8
|
end
|
10
|
-
|
9
|
+
|
11
10
|
context "contact validators" do
|
12
|
-
|
13
11
|
should "have a name" do
|
14
|
-
|
15
|
-
|
12
|
+
contact = @client.Contact.build
|
13
|
+
|
14
|
+
assert_equal(false, contact.valid?)
|
15
|
+
blank_error = contact.errors_for(:name).first
|
16
16
|
assert_not_nil(blank_error)
|
17
17
|
assert_equal("can't be blank", blank_error)
|
18
|
-
|
19
|
-
|
20
|
-
assert_equal(true,
|
21
|
-
assert_equal(0,
|
18
|
+
|
19
|
+
contact.name = "SOMETHING"
|
20
|
+
assert_equal(true, contact.valid?)
|
21
|
+
assert_equal(0, contact.errors.size)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "response parsing" do
|
26
|
+
it "parses default attributes" do
|
27
|
+
@instance = Xeroizer::Record::ContactModel.new(nil, "Contact")
|
28
|
+
|
29
|
+
some_xml = get_record_xml("contact")
|
30
|
+
|
31
|
+
result = @instance.parse_response(some_xml)
|
32
|
+
contact = result.response_items.first
|
33
|
+
|
34
|
+
keys = [:contact_id,
|
35
|
+
:contact_status,
|
36
|
+
:name,
|
37
|
+
:first_name,
|
38
|
+
:last_name,
|
39
|
+
:email_address,
|
40
|
+
:skype_user_name,
|
41
|
+
:bank_account_details,
|
42
|
+
:tax_number,
|
43
|
+
:accounts_receivable_tax_type,
|
44
|
+
:accounts_payable_tax_type,
|
45
|
+
:addresses,
|
46
|
+
:phones,
|
47
|
+
:updated_date_utc,
|
48
|
+
:is_supplier,
|
49
|
+
:is_customer,
|
50
|
+
:default_currency]
|
51
|
+
|
52
|
+
assert_equal(contact.attributes.keys, keys)
|
22
53
|
end
|
23
54
|
|
24
55
|
should "be able to have no name if has a contact_id" do
|
@@ -28,6 +59,49 @@ class ContactTest < Test::Unit::TestCase
|
|
28
59
|
assert_equal(0, @contact.errors.size)
|
29
60
|
end
|
30
61
|
|
62
|
+
it "parses extra attributes when present" do
|
63
|
+
@instance = Xeroizer::Record::ContactModel.new(nil, "Contact")
|
64
|
+
some_xml = get_record_xml("contact_with_details")
|
65
|
+
|
66
|
+
result = @instance.parse_response(some_xml)
|
67
|
+
contact = result.response_items.first
|
68
|
+
|
69
|
+
keys = [:contact_id,
|
70
|
+
:contact_status,
|
71
|
+
:name,
|
72
|
+
:first_name,
|
73
|
+
:last_name,
|
74
|
+
:email_address,
|
75
|
+
:skype_user_name,
|
76
|
+
:bank_account_details,
|
77
|
+
:tax_number,
|
78
|
+
:accounts_receivable_tax_type,
|
79
|
+
:accounts_payable_tax_type,
|
80
|
+
:addresses,
|
81
|
+
:phones,
|
82
|
+
:updated_date_utc,
|
83
|
+
:is_supplier,
|
84
|
+
:is_customer,
|
85
|
+
:default_currency,
|
86
|
+
:balances,
|
87
|
+
:batch_payments,
|
88
|
+
:payment_terms]
|
89
|
+
|
90
|
+
assert_equal(contact.attributes.keys, keys)
|
91
|
+
|
92
|
+
assert_equal(contact.balances.accounts_receivable.outstanding, 849.50)
|
93
|
+
assert_equal(contact.balances.accounts_receivable.overdue, 910.00)
|
94
|
+
assert_equal(contact.balances.accounts_payable.outstanding, 0.00)
|
95
|
+
assert_equal(contact.balances.accounts_payable.overdue, 0.00)
|
96
|
+
|
97
|
+
assert_equal(contact.batch_payments.bank_account_number, "123456")
|
98
|
+
assert_equal(contact.batch_payments.bank_account_name, "bank account")
|
99
|
+
assert_equal(contact.batch_payments.details, "details")
|
100
|
+
|
101
|
+
assert_equal(contact.payment_terms.bills.day, "4")
|
102
|
+
assert_equal(contact.payment_terms.bills.type, "OFFOLLOWINGMONTH")
|
103
|
+
assert_equal(contact.payment_terms.sales.day, "2")
|
104
|
+
assert_equal(contact.payment_terms.sales.type, "OFFOLLOWINGMONTH")
|
105
|
+
end
|
31
106
|
end
|
32
|
-
|
33
107
|
end
|
data/test/unit/oauth_test.rb
CHANGED
@@ -32,7 +32,15 @@ class OAuthTest < Test::Unit::TestCase
|
|
32
32
|
@client.Organisation.first
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
should "handle nonce used" do
|
37
|
+
Xeroizer::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("nonce_used"), :code => "401"))
|
35
38
|
|
39
|
+
assert_raises Xeroizer::OAuth::NonceUsed do
|
40
|
+
@client.Organisation.first
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
36
44
|
should "raise rate limit exceeded" do
|
37
45
|
Xeroizer::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("rate_limit_exceeded"), :code => "401"))
|
38
46
|
|
@@ -65,7 +73,18 @@ class OAuthTest < Test::Unit::TestCase
|
|
65
73
|
auto_rate_limit_client.Organisation.first
|
66
74
|
end
|
67
75
|
end
|
68
|
-
|
76
|
+
|
77
|
+
should "retry nonce_used failures a configurable number of times" do
|
78
|
+
nonce_used_client = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET, :nonce_used_max_attempts => 4)
|
79
|
+
Xeroizer::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("nonce_used"), :code => "401"))
|
80
|
+
|
81
|
+
nonce_used_client.expects(:sleep_for).with(1).times(4).returns(1)
|
82
|
+
|
83
|
+
assert_raises Xeroizer::OAuth::NonceUsed do
|
84
|
+
nonce_used_client.Organisation.first
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
69
88
|
should "handle unknown errors" do
|
70
89
|
Xeroizer::OAuth.any_instance.stubs(:get).returns(stub(:plain_body => get_file_as_string("bogus_oauth_error"), :code => "401"))
|
71
90
|
|
data/test/unit/report_test.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
class MockNonReportClassDefinition; end
|
4
|
+
|
3
5
|
class FactoryTest < Test::Unit::TestCase
|
4
6
|
include TestHelper
|
5
7
|
|
@@ -128,7 +130,16 @@ class FactoryTest < Test::Unit::TestCase
|
|
128
130
|
end
|
129
131
|
|
130
132
|
end
|
131
|
-
|
133
|
+
|
134
|
+
context "report factory in the dirty real world" do
|
135
|
+
|
136
|
+
should "not use inheritance to find report class" do
|
137
|
+
report = Xeroizer::Report::Factory.new(@client, :MockNonReportClassDefinition).klass
|
138
|
+
assert_equal(Xeroizer::Report::Base, report)
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
132
143
|
private
|
133
144
|
|
134
145
|
def check_valid_report_type(row)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xeroizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.16.
|
4
|
+
version: 2.16.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Robinson
|
@@ -242,7 +242,6 @@ extra_rdoc_files: []
|
|
242
242
|
files:
|
243
243
|
- LICENSE.txt
|
244
244
|
- README.md
|
245
|
-
- lib/big_decimal_to_s.rb
|
246
245
|
- lib/class_level_inheritable_attributes.rb
|
247
246
|
- lib/xeroizer.rb
|
248
247
|
- lib/xeroizer/application_http_proxy.rb
|
@@ -254,11 +253,16 @@ files:
|
|
254
253
|
- lib/xeroizer/http_encoding_helper.rb
|
255
254
|
- lib/xeroizer/logging.rb
|
256
255
|
- lib/xeroizer/models/account.rb
|
256
|
+
- lib/xeroizer/models/accounts_payable.rb
|
257
|
+
- lib/xeroizer/models/accounts_receivable.rb
|
257
258
|
- lib/xeroizer/models/address.rb
|
258
259
|
- lib/xeroizer/models/allocation.rb
|
259
260
|
- lib/xeroizer/models/attachment.rb
|
261
|
+
- lib/xeroizer/models/balances.rb
|
260
262
|
- lib/xeroizer/models/bank_account.rb
|
261
263
|
- lib/xeroizer/models/bank_transaction.rb
|
264
|
+
- lib/xeroizer/models/batch_payments.rb
|
265
|
+
- lib/xeroizer/models/bills.rb
|
262
266
|
- lib/xeroizer/models/branding_theme.rb
|
263
267
|
- lib/xeroizer/models/contact.rb
|
264
268
|
- lib/xeroizer/models/contact_group.rb
|
@@ -285,10 +289,13 @@ files:
|
|
285
289
|
- lib/xeroizer/models/option.rb
|
286
290
|
- lib/xeroizer/models/organisation.rb
|
287
291
|
- lib/xeroizer/models/payment.rb
|
292
|
+
- lib/xeroizer/models/payment_terms.rb
|
288
293
|
- lib/xeroizer/models/phone.rb
|
289
294
|
- lib/xeroizer/models/prepayment.rb
|
295
|
+
- lib/xeroizer/models/purchase_order.rb
|
290
296
|
- lib/xeroizer/models/receipt.rb
|
291
297
|
- lib/xeroizer/models/repeating_invoice.rb
|
298
|
+
- lib/xeroizer/models/sales.rb
|
292
299
|
- lib/xeroizer/models/schedule.rb
|
293
300
|
- lib/xeroizer/models/tax_component.rb
|
294
301
|
- lib/xeroizer/models/tax_rate.rb
|
@@ -336,6 +343,7 @@ files:
|
|
336
343
|
- test/stub_responses/bogus_oauth_error
|
337
344
|
- test/stub_responses/branding_themes.xml
|
338
345
|
- test/stub_responses/contact.xml
|
346
|
+
- test/stub_responses/contact_with_details.xml
|
339
347
|
- test/stub_responses/contacts.xml
|
340
348
|
- test/stub_responses/create_credit_note.xml
|
341
349
|
- test/stub_responses/create_invoice.xml
|
@@ -353,6 +361,7 @@ files:
|
|
353
361
|
- test/stub_responses/items.xml
|
354
362
|
- test/stub_responses/manual_journal.xml
|
355
363
|
- test/stub_responses/manual_journals.xml
|
364
|
+
- test/stub_responses/nonce_used
|
356
365
|
- test/stub_responses/organisation.xml
|
357
366
|
- test/stub_responses/organisations.xml
|
358
367
|
- test/stub_responses/payments.xml
|
@@ -619,7 +628,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
619
628
|
version: '0'
|
620
629
|
requirements: []
|
621
630
|
rubyforge_project:
|
622
|
-
rubygems_version: 2.
|
631
|
+
rubygems_version: 2.5.1
|
623
632
|
signing_key:
|
624
633
|
specification_version: 4
|
625
634
|
summary: Xero library
|
@@ -634,6 +643,7 @@ test_files:
|
|
634
643
|
- test/stub_responses/bogus_oauth_error
|
635
644
|
- test/stub_responses/branding_themes.xml
|
636
645
|
- test/stub_responses/contact.xml
|
646
|
+
- test/stub_responses/contact_with_details.xml
|
637
647
|
- test/stub_responses/contacts.xml
|
638
648
|
- test/stub_responses/create_credit_note.xml
|
639
649
|
- test/stub_responses/create_invoice.xml
|
@@ -651,6 +661,7 @@ test_files:
|
|
651
661
|
- test/stub_responses/items.xml
|
652
662
|
- test/stub_responses/manual_journal.xml
|
653
663
|
- test/stub_responses/manual_journals.xml
|
664
|
+
- test/stub_responses/nonce_used
|
654
665
|
- test/stub_responses/organisation.xml
|
655
666
|
- test/stub_responses/organisations.xml
|
656
667
|
- test/stub_responses/payments.xml
|
@@ -897,4 +908,3 @@ test_files:
|
|
897
908
|
- test/unit/record_definition_test.rb
|
898
909
|
- test/unit/report_definition_test.rb
|
899
910
|
- test/unit/report_test.rb
|
900
|
-
has_rdoc:
|