quickeebooks 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/HISTORY.md +4 -0
- data/lib/quickeebooks.rb +8 -0
- data/lib/quickeebooks/online/model/web_site.rb +1 -0
- data/lib/quickeebooks/online/service/access_token.rb +11 -0
- data/lib/quickeebooks/shared/service/access_token.rb +43 -0
- data/lib/quickeebooks/shared/service/filter.rb +3 -3
- data/lib/quickeebooks/version.rb +1 -1
- data/lib/quickeebooks/windows/model/account_reference.rb +5 -1
- data/lib/quickeebooks/windows/model/credit_charge_info.rb +2 -2
- data/lib/quickeebooks/windows/model/sales_receipt.rb +33 -0
- data/lib/quickeebooks/windows/model/sales_receipt_header.rb +57 -0
- data/lib/quickeebooks/windows/model/sales_receipt_line_item.rb +40 -0
- data/lib/quickeebooks/windows/service/access_token.rb +11 -0
- data/lib/quickeebooks/windows/service/account.rb +1 -1
- data/lib/quickeebooks/windows/service/item.rb +14 -0
- data/lib/quickeebooks/windows/service/sales_receipt.rb +39 -0
- data/spec/quickeebooks/online/services/customer_spec.rb +9 -0
- data/spec/quickeebooks/online/services/filter_spec.rb +16 -1
- data/spec/quickeebooks/shared/access_token_spec.rb +134 -0
- data/spec/xml/online/customer.xml +3 -1
- data/spec/xml/shared/disconnect_invalid.xml +6 -0
- data/spec/xml/shared/disconnect_success.xml +5 -0
- data/spec/xml/shared/reconnect_error_expired.xml +6 -0
- data/spec/xml/shared/reconnect_error_not_approved.xml +6 -0
- data/spec/xml/shared/reconnect_error_out_of_bounds.xml +6 -0
- data/spec/xml/shared/reconnect_success.xml +8 -0
- metadata +15 -1
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 0.1.1 (2013-01-16)
|
2
|
+
|
3
|
+
* Quickeebooks can now re-authorize a token via `Quickeebooks::Shared::Service::AccessToken.reconnect`. In addition destroying an access token can now be done via `Quickeebooks::Shared::Service::AccessToken.disconnect`. Thank you to `FundingGates` for the contribution.
|
4
|
+
|
1
5
|
## 0.1.0 (2013-01-16)
|
2
6
|
|
3
7
|
* Quickbooks Online now supports a single HTTP endpoint for API calls, no need to first determine the Base URL. `Quickeebooks::Online::ServiceBase` has been adjusted to use a single API endpoint.
|
data/lib/quickeebooks.rb
CHANGED
@@ -55,6 +55,7 @@ end
|
|
55
55
|
|
56
56
|
# Services
|
57
57
|
require 'quickeebooks/shared/service/filter'
|
58
|
+
require 'quickeebooks/shared/service/access_token'
|
58
59
|
|
59
60
|
#== Online
|
60
61
|
|
@@ -90,6 +91,7 @@ require 'quickeebooks/online/service/invoice'
|
|
90
91
|
require 'quickeebooks/online/service/item'
|
91
92
|
require 'quickeebooks/online/service/entitlement'
|
92
93
|
require 'quickeebooks/online/service/payment'
|
94
|
+
require 'quickeebooks/online/service/access_token'
|
93
95
|
|
94
96
|
#== Windows
|
95
97
|
|
@@ -125,6 +127,10 @@ require 'quickeebooks/windows/model/credit_card'
|
|
125
127
|
require 'quickeebooks/windows/model/credit_charge_info'
|
126
128
|
require 'quickeebooks/windows/model/credit_charge_response'
|
127
129
|
require 'quickeebooks/windows/model/clazz'
|
130
|
+
require 'quickeebooks/windows/model/sales_receipt_header'
|
131
|
+
require 'quickeebooks/windows/model/sales_receipt_line_item'
|
132
|
+
require 'quickeebooks/windows/model/sales_receipt'
|
133
|
+
|
128
134
|
|
129
135
|
# Services
|
130
136
|
require 'quickeebooks/windows/service/filter'
|
@@ -134,9 +140,11 @@ require 'quickeebooks/windows/service/customer'
|
|
134
140
|
require 'quickeebooks/windows/service/item'
|
135
141
|
require 'quickeebooks/windows/service/invoice'
|
136
142
|
require 'quickeebooks/windows/service/sales_rep'
|
143
|
+
require 'quickeebooks/windows/service/sales_receipt'
|
137
144
|
require 'quickeebooks/windows/service/ship_method'
|
138
145
|
require 'quickeebooks/windows/service/sales_tax'
|
139
146
|
require 'quickeebooks/windows/service/customer_msg'
|
140
147
|
require 'quickeebooks/windows/service/company_meta_data'
|
141
148
|
require 'quickeebooks/windows/service/payment'
|
142
149
|
require 'quickeebooks/windows/service/clazz'
|
150
|
+
require 'quickeebooks/windows/service/access_token'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "quickeebooks"
|
2
|
+
|
3
|
+
# See https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0025_Intuit_Anywhere/0020_Connect/0010_From_Within_Your_App/Implement_OAuth_in_Your_App/Token_Renewal_and_Expiration
|
4
|
+
module Quickeebooks
|
5
|
+
module Shared
|
6
|
+
module Service
|
7
|
+
class AccessTokenResponse
|
8
|
+
include ROXML
|
9
|
+
|
10
|
+
xml_convention :camelcase
|
11
|
+
xml_accessor :error_code
|
12
|
+
xml_accessor :error_message
|
13
|
+
xml_accessor :token, :from => 'OAuthToken'
|
14
|
+
xml_accessor :secret, :from => 'OAuthTokenSecret'
|
15
|
+
|
16
|
+
def error?
|
17
|
+
error_code.to_i != 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
module AccessToken
|
21
|
+
# see https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0025_Intuit_Anywhere/0060_Reference/3002_Reconnect_API
|
22
|
+
def reconnect
|
23
|
+
response = do_http_get("https://appcenter.intuit.com/api/v1/Connection/Reconnect")
|
24
|
+
if response && response.code.to_i == 200
|
25
|
+
Quickeebooks::Shared::Service::AccessTokenResponse.from_xml(response.body)
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# see https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0025_Intuit_Anywhere/0060_Reference/3001_Disconnect_API
|
32
|
+
def disconnect
|
33
|
+
response = do_http_get("https://appcenter.intuit.com/api/v1/Connection/Disconnect")
|
34
|
+
if response && response.code.to_i == 200
|
35
|
+
Quickeebooks::Shared::Service::AccessTokenResponse.from_xml(response.body)
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -44,13 +44,13 @@ module Quickeebooks
|
|
44
44
|
def number_to_s
|
45
45
|
clauses = []
|
46
46
|
if @eq
|
47
|
-
clauses << "#{@field} :EQUALS: #{@
|
47
|
+
clauses << "#{@field} :EQUALS: #{@eq}"
|
48
48
|
end
|
49
49
|
if @gt
|
50
|
-
clauses << "#{@field} :GreaterThan: #{@
|
50
|
+
clauses << "#{@field} :GreaterThan: #{@gt}"
|
51
51
|
end
|
52
52
|
if @lt
|
53
|
-
clauses << "#{@field} :LessThan: #{@
|
53
|
+
clauses << "#{@field} :LessThan: #{@lt}"
|
54
54
|
end
|
55
55
|
clauses.join(" :AND: ")
|
56
56
|
end
|
data/lib/quickeebooks/version.rb
CHANGED
@@ -8,10 +8,14 @@ module Quickeebooks
|
|
8
8
|
xml_accessor :account_name, :from => 'AccountName'
|
9
9
|
xml_accessor :account_type, :from => 'AccountType'
|
10
10
|
|
11
|
-
def initialize(account_id = nil)
|
11
|
+
def initialize(account_id = nil, account_name = nil)
|
12
12
|
unless account_id.nil?
|
13
13
|
self.account_id = account_id
|
14
14
|
end
|
15
|
+
|
16
|
+
unless account_name.nil?
|
17
|
+
self.account_name = account_name
|
18
|
+
end
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
@@ -6,8 +6,8 @@ module Quickeebooks
|
|
6
6
|
xml_accessor :number, :from => 'Number'
|
7
7
|
xml_accessor :type, :from => 'Type'
|
8
8
|
xml_accessor :name_on_acct, :from => 'NameOnAcct'
|
9
|
-
xml_accessor :cc_expiration_month, :from => '
|
10
|
-
xml_accessor :cc_expiration_year, :from => '
|
9
|
+
xml_accessor :cc_expiration_month, :from => 'CcExpirMn', :as => Integer
|
10
|
+
xml_accessor :cc_expiration_year, :from => 'CcExpirYr', :as => Integer
|
11
11
|
xml_accessor :billing_address_street, :from => 'BillAddrStreet'
|
12
12
|
xml_accessor :zip_code, :from => 'ZipCode'
|
13
13
|
xml_accessor :cvv, :from => 'Ccv'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'quickeebooks'
|
2
|
+
require 'quickeebooks/windows/model/id'
|
3
|
+
require 'quickeebooks/windows/model/external_key'
|
4
|
+
require 'quickeebooks/windows/model/meta_data'
|
5
|
+
|
6
|
+
module Quickeebooks
|
7
|
+
module Windows
|
8
|
+
module Model
|
9
|
+
class SalesReceipt < Quickeebooks::Windows::Model::IntuitType
|
10
|
+
|
11
|
+
XML_COLLECTION_NODE = 'SalesReceipts'
|
12
|
+
XML_NODE = 'SalesReceipt'
|
13
|
+
|
14
|
+
# https://services.intuit.com/sb/salesreceipt/v2/<realmID>
|
15
|
+
REST_RESOURCE = "salesreceipt"
|
16
|
+
|
17
|
+
xml_convention :camelcase
|
18
|
+
xml_accessor :id, :as => Quickeebooks::Windows::Model::Id
|
19
|
+
xml_accessor :meta_data, :from => 'MetaData', :as => Quickeebooks::Windows::Model::MetaData
|
20
|
+
xml_accessor :external_key, :as => Quickeebooks::Windows::Model::ExternalKey
|
21
|
+
xml_accessor :synchronized
|
22
|
+
xml_accessor :header, :from => 'Header', :as => Quickeebooks::Windows::Model::SalesReceiptHeader
|
23
|
+
xml_accessor :line_items, :from => 'Line', :as => [Quickeebooks::Windows::Model::SalesReceiptLineItem]
|
24
|
+
xml_accessor :tax_line, :from => 'TaxLine', :as => Quickeebooks::Windows::Model::TaxLine
|
25
|
+
|
26
|
+
def valid_for_create?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Quickeebooks
|
4
|
+
module Windows
|
5
|
+
module Model
|
6
|
+
class SalesReceiptHeader < Quickeebooks::Windows::Model::IntuitType
|
7
|
+
|
8
|
+
xml_name 'Header'
|
9
|
+
xml_accessor :doc_number, :from => 'DocNumber'
|
10
|
+
xml_accessor :txn_date, :from => 'TxnDate', :as => Time
|
11
|
+
xml_accessor :currency, :from => 'Currency'
|
12
|
+
xml_accessor :msg, :from => 'Msg'
|
13
|
+
xml_accessor :note, :from => 'Note'
|
14
|
+
xml_accessor :status, :from => 'Status'
|
15
|
+
xml_accessor :customer_id, :from => 'CustomerId', :as => Quickeebooks::Windows::Model::Id
|
16
|
+
xml_accessor :customer_name, :from => 'CustomerName'
|
17
|
+
xml_accessor :job_id, :from => 'JobId', :as => Quickeebooks::Windows::Model::Id
|
18
|
+
xml_accessor :job_name, :from => 'JobName'
|
19
|
+
xml_accessor :remit_to_id, :from => 'RemitToId', :as => Quickeebooks::Windows::Model::Id
|
20
|
+
xml_accessor :remit_to_name, :from => 'RemitToName'
|
21
|
+
xml_accessor :class_id, :from => 'ClassId', :as => Quickeebooks::Windows::Model::Id
|
22
|
+
xml_accessor :class_name, :from => 'ClassName'
|
23
|
+
xml_accessor :sales_rep_id, :from => 'SalesRepId', :as => Quickeebooks::Windows::Model::Id
|
24
|
+
xml_accessor :sales_rep_name, :from => 'SalesRepName'
|
25
|
+
xml_accessor :sales_tax_code_id, :from => 'SalesTaxCodeId', :as => Quickeebooks::Windows::Model::Id
|
26
|
+
xml_accessor :sales_tax_code_name, :from => 'SalesTaxCodeName'
|
27
|
+
xml_accessor :po_number, :from => 'PONumber'
|
28
|
+
xml_accessor :fob
|
29
|
+
xml_accessor :ship_date, :from => 'ShipDate', :as => Time
|
30
|
+
xml_accessor :sub_total_amount, :from => 'SubTotalAmt', :as => Float
|
31
|
+
xml_accessor :tax_id, :from => 'TaxId' # FEIN
|
32
|
+
xml_accessor :tax_name, :from => 'TaxName' # Business Name related to the FEIN
|
33
|
+
xml_accessor :tax_group_id, :from => 'TaxGroupId', :as => Quickeebooks::Windows::Model::Id
|
34
|
+
xml_accessor :tax_group_name, :from => 'TaxGroupName'
|
35
|
+
xml_accessor :tax_rate, :from => 'TaxRate', :as => Float
|
36
|
+
xml_accessor :tax_amount, :from => 'TaxAmt', :as => Float
|
37
|
+
xml_accessor :total_amount, :from => 'TotalAmt', :as => Float
|
38
|
+
xml_accessor :to_be_printed, :from => 'ToBePrinted'
|
39
|
+
xml_accessor :to_be_emailed, :from => 'ToBeEmailed'
|
40
|
+
xml_accessor :custom, :from => 'Custom'
|
41
|
+
xml_accessor :shipping_address, :from => 'ShipAddr', :as => Quickeebooks::Windows::Model::Address
|
42
|
+
xml_accessor :ship_method_id, :from => 'ShipMethodId', :as => Quickeebooks::Windows::Model::Id
|
43
|
+
xml_accessor :ship_method_name, :from => 'ShipMethodName'
|
44
|
+
xml_accessor :deposit_to_account_id, :from => "DepositToAccountId"
|
45
|
+
xml_accessor :deposit_to_account_name, :from => "DepositToAccountName"
|
46
|
+
xml_accessor :payment_method_id, :from => "PaymentMethodId", :as => Quickeebooks::Windows::Model::Id
|
47
|
+
xml_accessor :payment_method_name, :from => "PaymentMethodName"
|
48
|
+
xml_accessor :detail, :from => 'Detail', :as => Quickeebooks::Online::Model::PaymentDetail
|
49
|
+
xml_accessor :discount_amount, :from => 'DiscountAmt', :as => Float
|
50
|
+
xml_accessor :discount_rate, :from => 'DiscountRate', :as => Float
|
51
|
+
xml_accessor :discount_account_id, :from => 'DiscountAccountId'
|
52
|
+
xml_accessor :discount_account_name, :from => 'DiscountAccountName'
|
53
|
+
xml_accessor :discount_taxable, :from => 'DiscountTaxable'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Quickeebooks
|
2
|
+
module Windows
|
3
|
+
module Model
|
4
|
+
class SalesReceiptLineItem < Quickeebooks::Windows::Model::IntuitType
|
5
|
+
xml_name 'Line'
|
6
|
+
xml_accessor :id, :from => 'Id', :as => Quickeebooks::Windows::Model::Id
|
7
|
+
xml_accessor :desc, :from => 'Desc'
|
8
|
+
xml_accessor :group_member, :from => 'GroupMember'
|
9
|
+
xml_accessor :custom_fields, :from => 'CustomField', :as => [Quickeebooks::Windows::Model::CustomField]
|
10
|
+
xml_accessor :amount, :from => 'Amount', :as => Float
|
11
|
+
xml_accessor :class_id, :from => 'ClassId', :as => Quickeebooks::Windows::Model::Id
|
12
|
+
xml_accessor :class_name, :from => 'ClassName'
|
13
|
+
xml_accessor :taxable, :from => 'Taxable'
|
14
|
+
xml_accessor :item_id, :from => 'ItemId', :as => Quickeebooks::Windows::Model::Id
|
15
|
+
xml_accessor :item_name, :from => 'ItemName'
|
16
|
+
xml_accessor :item_type, :from => 'ItemType'
|
17
|
+
xml_accessor :unit_price, :from => 'UnitPrice', :as => Float
|
18
|
+
xml_accessor :rate_percent, :from => 'RatePercent', :as => Float
|
19
|
+
xml_accessor :price_level_id, :from => 'PriceLevelId', :as => Quickeebooks::Windows::Model::Id
|
20
|
+
xml_accessor :price_level_name, :from => 'PriceLevelName'
|
21
|
+
xml_accessor :uom_id, :from => 'UOMId'
|
22
|
+
xml_accessor :uom_abbrev, :from => 'UOMAbbrv'
|
23
|
+
xml_accessor :override_item_account_id, :from => 'OverrideItemAccountId'
|
24
|
+
xml_accessor :override_item_account_name, :from => 'OverrideItemAccountName'
|
25
|
+
xml_accessor :discount_id, :from => 'DiscountId', :as => Quickeebooks::Windows::Model::Id
|
26
|
+
xml_accessor :discount_name, :from => 'DiscountName'
|
27
|
+
xml_accessor :quantity, :from => 'Qty', :as => Float
|
28
|
+
|
29
|
+
xml_accessor :discount_amount, :from => 'DiscountAmount', :as => Float
|
30
|
+
xml_accessor :discount_rate_percent, :from => 'DiscountRatePercent', :as => Float
|
31
|
+
|
32
|
+
xml_accessor :sales_tax_code_id, :from => 'SalesTaxCodeId', :as => Quickeebooks::Windows::Model::Id
|
33
|
+
xml_accessor :sales_tax_code_name, :from => 'SalesTaxCodeName'
|
34
|
+
xml_accessor :service_date, :from => 'ServiceDate', :as => Time
|
35
|
+
xml_accessor :custom1, :from => 'Custom1'
|
36
|
+
xml_accessor :custom2, :from => 'Custom2'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -7,7 +7,7 @@ module Quickeebooks
|
|
7
7
|
class Account < Quickeebooks::Windows::Service::ServiceBase
|
8
8
|
|
9
9
|
def list(filters = [], page = 1, per_page = 20, sort = nil, options = {})
|
10
|
-
fetch_collection(
|
10
|
+
fetch_collection(Quickeebooks::Windows::Model::Account, nil, filters, page, per_page, sort, options)
|
11
11
|
end
|
12
12
|
|
13
13
|
end
|
@@ -14,6 +14,20 @@ module Quickeebooks
|
|
14
14
|
fetch_collection(Quickeebooks::Windows::Model::Item, custom_field_query.strip, filters, page, per_page, sort, options)
|
15
15
|
end
|
16
16
|
|
17
|
+
def create(item)
|
18
|
+
# XML is a wrapped 'object' where the type is specified as an attribute
|
19
|
+
# <Object xsi:type="Item">
|
20
|
+
xml_node = item.to_xml(:name => 'Object')
|
21
|
+
xml_node.set_attribute('xsi:type', 'Item')
|
22
|
+
xml = <<-XML
|
23
|
+
<Add xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" RequestId="#{guid}" xmlns="http://www.intuit.com/sb/cdm/v2">
|
24
|
+
<ExternalRealmId>#{self.realm_id}</ExternalRealmId>
|
25
|
+
#{xml_node}
|
26
|
+
</Add>
|
27
|
+
XML
|
28
|
+
perform_write(Quickeebooks::Windows::Model::Item, xml)
|
29
|
+
end
|
30
|
+
|
17
31
|
end
|
18
32
|
end
|
19
33
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'quickeebooks/windows/model/sales_receipt'
|
2
|
+
require 'quickeebooks/windows/model/sales_receipt_header'
|
3
|
+
require 'quickeebooks/windows/model/sales_receipt_line_item'
|
4
|
+
require 'quickeebooks/windows/service/service_base'
|
5
|
+
|
6
|
+
module Quickeebooks
|
7
|
+
module Windows
|
8
|
+
module Service
|
9
|
+
class SalesReceipt < Quickeebooks::Windows::Service::ServiceBase
|
10
|
+
|
11
|
+
def list(filters = [], page = 1, per_page = 20, sort = nil, options = {})
|
12
|
+
custom_field_query = '<?xml version="1.0" encoding="utf-8"?>'
|
13
|
+
custom_field_query += '<SalesReceiptQuery xmlns="http://www.intuit.com/sb/cdm/v2">'
|
14
|
+
custom_field_query += "<StartPage>#{page}</StartPage><ChunkSize>#{per_page}</ChunkSize>"
|
15
|
+
custom_field_query += '<CustomFieldEnable>true</CustomFieldEnable></SalesReceiptQuery>'
|
16
|
+
fetch_collection(Quickeebooks::Windows::Model::SalesReceipt, custom_field_query.strip, filters, page, per_page, sort, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create(sales_receipt)
|
20
|
+
raise InvalidModelException unless sales_receipt.valid_for_create?
|
21
|
+
|
22
|
+
# XML is a wrapped 'object' where the type is specified as an attribute
|
23
|
+
# <Object xsi:type="Invoice">
|
24
|
+
xml_node = sales_receipt.to_xml(:name => 'Object')
|
25
|
+
xml_node.set_attribute('xsi:type', 'SalesReceipt')
|
26
|
+
xml = <<-XML
|
27
|
+
<Add xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" RequestId="#{guid}" xmlns="http://www.intuit.com/sb/cdm/v2">
|
28
|
+
<ExternalRealmId>#{self.realm_id}</ExternalRealmId>
|
29
|
+
#{xml_node}
|
30
|
+
</Add>
|
31
|
+
XML
|
32
|
+
perform_write(Quickeebooks::Windows::Model::SalesReceipt, xml)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -102,5 +102,14 @@ describe "Quickeebooks::Online::Service::Customer" do
|
|
102
102
|
updated.name.should == "Billy Bob"
|
103
103
|
end
|
104
104
|
|
105
|
+
it 'Can update a fetched customer' do
|
106
|
+
xml = File.read(File.dirname(__FILE__) + "/../../../xml/online/customer.xml")
|
107
|
+
url = "#{@service.url_for_resource(Quickeebooks::Online::Model::Customer.resource_for_singular)}/99"
|
108
|
+
FakeWeb.register_uri(:get, url, :status => ["200", "OK"], :body => xml)
|
109
|
+
customer = @service.fetch_by_id(99)
|
110
|
+
url = "#{@service.url_for_resource(Quickeebooks::Online::Model::Customer.resource_for_singular)}/#{customer.id.value}"
|
111
|
+
FakeWeb.register_uri(:post, url, :status => ["200", "OK"], :body => xml)
|
112
|
+
updated = @service.update(customer)
|
113
|
+
end
|
105
114
|
|
106
115
|
end
|
@@ -6,7 +6,7 @@ require "quickeebooks"
|
|
6
6
|
describe "Quickeebooks::Online::Service::Filter" do
|
7
7
|
before(:all) do
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it "can generate a text filter" do
|
11
11
|
filter = Quickeebooks::Online::Service::Filter.new(:text, :field => "Name", :value => "Smith")
|
12
12
|
filter.to_s.should == "Name :EQUALS: Smith"
|
@@ -29,6 +29,21 @@ describe "Quickeebooks::Online::Service::Filter" do
|
|
29
29
|
filter.to_s.should == "CreateTime :AFTER: #{time.strftime(Quickeebooks::Online::Service::Filter::DATE_TIME_FORMAT)}"
|
30
30
|
end
|
31
31
|
|
32
|
+
it "can generate a number filter with equals" do
|
33
|
+
filter = Quickeebooks::Online::Service::Filter.new(:number, :field => "OpenBalance", :eq => 5)
|
34
|
+
filter.to_s.should == "OpenBalance :EQUALS: 5"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can generate a number filter with greater than" do
|
38
|
+
filter = Quickeebooks::Online::Service::Filter.new(:number, :field => "OpenBalance", :gt => 5)
|
39
|
+
filter.to_s.should == "OpenBalance :GreaterThan: 5"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can generate a number filter with less than" do
|
43
|
+
filter = Quickeebooks::Online::Service::Filter.new(:number, :field => "OpenBalance", :lt => 5)
|
44
|
+
filter.to_s.should == "OpenBalance :LessThan: 5"
|
45
|
+
end
|
46
|
+
|
32
47
|
it "can generate a datetime filter with bounded dates" do
|
33
48
|
time1 = Time.mktime(2012, 1, 2, 1)
|
34
49
|
time2 = Time.mktime(2012, 1, 5, 8)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "fakeweb"
|
3
|
+
require "oauth"
|
4
|
+
require "quickeebooks"
|
5
|
+
|
6
|
+
describe "Quickeebooks::Shared::Service::AccessToken" do
|
7
|
+
|
8
|
+
shared_examples "access_token_operations" do
|
9
|
+
context "reconnect" do
|
10
|
+
let(:reconnect_url){ "https://appcenter.intuit.com/api/v1/Connection/Reconnect" }
|
11
|
+
|
12
|
+
it "can successfully reconnect" do
|
13
|
+
xml = File.read(File.dirname(__FILE__) + "/../../xml/shared/reconnect_success.xml")
|
14
|
+
FakeWeb.register_uri(:get, reconnect_url, :status => ["200", "OK"], :body => xml)
|
15
|
+
|
16
|
+
response = @service.reconnect
|
17
|
+
|
18
|
+
response.error?.should be_false
|
19
|
+
response.token.should == "qye2eIdQ5H5yMyrlJflUWh712xfFXjyNnW1MfbC0rz04TfCP"
|
20
|
+
response.secret.should == "cyDeUNQTkFzoR0KkDn7viN6uLQxWTobeEUKW7I79"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can handle expired tokens" do
|
24
|
+
xml = File.read(File.dirname(__FILE__) + "/../../xml/shared/reconnect_error_expired.xml")
|
25
|
+
FakeWeb.register_uri(:get, reconnect_url, :status => ["200", "OK"], :body => xml)
|
26
|
+
|
27
|
+
response = @service.reconnect
|
28
|
+
|
29
|
+
response.error?.should be_true
|
30
|
+
response.error_code.should == "270"
|
31
|
+
response.error_message.should == "OAuth Token Rejected"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can handle out-of-bounds refresh windows" do
|
35
|
+
xml = File.read(File.dirname(__FILE__) + "/../../xml/shared/reconnect_error_out_of_bounds.xml")
|
36
|
+
FakeWeb.register_uri(:get, reconnect_url, :status => ["200", "OK"], :body => xml)
|
37
|
+
|
38
|
+
response = @service.reconnect
|
39
|
+
|
40
|
+
response.error?.should be_true
|
41
|
+
response.error_code.should == "212"
|
42
|
+
response.error_message.should == "Token Refresh Window Out of Bounds"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
it "can handle unapproved apps" do
|
47
|
+
xml = File.read(File.dirname(__FILE__) + "/../../xml/shared/reconnect_error_not_approved.xml")
|
48
|
+
FakeWeb.register_uri(:get, reconnect_url, :status => ["200", "OK"], :body => xml)
|
49
|
+
|
50
|
+
response = @service.reconnect
|
51
|
+
|
52
|
+
response.error?.should be_true
|
53
|
+
response.error_code.should == "24"
|
54
|
+
response.error_message.should == "Invalid App Token"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "disconnect" do
|
59
|
+
let(:disconnect_url){ "https://appcenter.intuit.com/api/v1/Connection/Disconnect" }
|
60
|
+
|
61
|
+
it "can successfully disconnect" do
|
62
|
+
xml = File.read(File.dirname(__FILE__) + "/../../xml/shared/disconnect_success.xml")
|
63
|
+
FakeWeb.register_uri(:get, disconnect_url, :status => ["200", "OK"], :body => xml)
|
64
|
+
|
65
|
+
response = @service.disconnect
|
66
|
+
|
67
|
+
response.error?.should be_false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can handle invalid tokens" do
|
71
|
+
xml = File.read(File.dirname(__FILE__) + "/../../xml/shared/disconnect_invalid.xml")
|
72
|
+
FakeWeb.register_uri(:get, disconnect_url, :status => ["200", "OK"], :body => xml)
|
73
|
+
|
74
|
+
response = @service.disconnect
|
75
|
+
|
76
|
+
response.error?.should be_true
|
77
|
+
response.error_code.should == "270"
|
78
|
+
response.error_message.should == "OAuth Token rejected"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "online" do
|
84
|
+
before(:all) do
|
85
|
+
FakeWeb.allow_net_connect = false
|
86
|
+
qb_key = "key"
|
87
|
+
qb_secret = "secreet"
|
88
|
+
|
89
|
+
@realm_id = "9991111222"
|
90
|
+
@oauth_consumer = OAuth::Consumer.new(qb_key, qb_key, {
|
91
|
+
:site => "https://oauth.intuit.com",
|
92
|
+
:request_token_path => "/oauth/v1/get_request_token",
|
93
|
+
:authorize_path => "/oauth/v1/get_access_token",
|
94
|
+
:access_token_path => "/oauth/v1/get_access_token"
|
95
|
+
})
|
96
|
+
@oauth = OAuth::AccessToken.new(@oauth_consumer, "blah", "blah")
|
97
|
+
|
98
|
+
@service = Quickeebooks::Online::Service::AccessToken.new
|
99
|
+
@service.access_token = @oauth
|
100
|
+
@service.instance_eval {
|
101
|
+
@realm_id = "9991111222"
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
it_behaves_like "access_token_operations"
|
106
|
+
end
|
107
|
+
|
108
|
+
context "windows" do
|
109
|
+
before(:all) do
|
110
|
+
FakeWeb.allow_net_connect = false
|
111
|
+
qb_key = "key"
|
112
|
+
qb_secret = "secreet"
|
113
|
+
|
114
|
+
@realm_id = "9991111222"
|
115
|
+
#@base_uri = "https://qbo.intuit.com/qbo36"
|
116
|
+
@oauth_consumer = OAuth::Consumer.new(qb_key, qb_key, {
|
117
|
+
:site => "https://oauth.intuit.com",
|
118
|
+
:request_token_path => "/oauth/v1/get_request_token",
|
119
|
+
:authorize_path => "/oauth/v1/get_access_token",
|
120
|
+
:access_token_path => "/oauth/v1/get_access_token"
|
121
|
+
})
|
122
|
+
@oauth = OAuth::AccessToken.new(@oauth_consumer, "blah", "blah")
|
123
|
+
|
124
|
+
@service = Quickeebooks::Windows::Service::AccessToken.new
|
125
|
+
|
126
|
+
@service.access_token = @oauth
|
127
|
+
@service.instance_eval {
|
128
|
+
@realm_id = "9991111222"
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
it_behaves_like "access_token_operations"
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<PlatformResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
|
3
|
+
<ErrorMessage>OAuth Token rejected</ErrorMessage>
|
4
|
+
<ErrorCode>270</ErrorCode>
|
5
|
+
<ServerTime>2011-11-24T17:45:27.11097Z</ServerTime>
|
6
|
+
</PlatformResponse>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<PlatformResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
|
3
|
+
<ErrorCode>0</ErrorCode>
|
4
|
+
<ServerTime>2011-11-23T17:15:27.21097Z</ServerTime>
|
5
|
+
</PlatformResponse>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<ReconnectResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
|
3
|
+
<ErrorMessage>OAuth Token Rejected</ErrorMessage>
|
4
|
+
<ErrorCode>270</ErrorCode>
|
5
|
+
<ServerTime>2012-01-04T19:21:21.0782072Z</ServerTime>
|
6
|
+
</ReconnectResponse>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<ReconnectResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
|
3
|
+
<ErrorMessage>Invalid App Token</ErrorMessage>
|
4
|
+
<ErrorCode>24</ErrorCode>
|
5
|
+
<ServerTime>2012-01-04T19:21:21.0782072Z</ServerTime>
|
6
|
+
</ReconnectResponse>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<ReconnectResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
|
3
|
+
<ErrorMessage>Token Refresh Window Out of Bounds</ErrorMessage>
|
4
|
+
<ErrorCode>212</ErrorCode>
|
5
|
+
<ServerTime>2012-01-04T19:21:21.0782072Z</ServerTime>
|
6
|
+
</ReconnectResponse>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<ReconnectResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
|
3
|
+
<ErrorMessage />
|
4
|
+
<ErrorCode>0</ErrorCode>
|
5
|
+
<ServerTime>2012-01-04T19:21:21.0782072Z</ServerTime>
|
6
|
+
<OAuthToken>qye2eIdQ5H5yMyrlJflUWh712xfFXjyNnW1MfbC0rz04TfCP</OAuthToken>
|
7
|
+
<OAuthTokenSecret>cyDeUNQTkFzoR0KkDn7viN6uLQxWTobeEUKW7I79</OAuthTokenSecret>
|
8
|
+
</ReconnectResponse>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quickeebooks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -209,6 +209,7 @@ files:
|
|
209
209
|
- lib/quickeebooks/online/model/purchase_cost.rb
|
210
210
|
- lib/quickeebooks/online/model/unit_price.rb
|
211
211
|
- lib/quickeebooks/online/model/web_site.rb
|
212
|
+
- lib/quickeebooks/online/service/access_token.rb
|
212
213
|
- lib/quickeebooks/online/service/account.rb
|
213
214
|
- lib/quickeebooks/online/service/company_meta_data.rb
|
214
215
|
- lib/quickeebooks/online/service/customer.rb
|
@@ -220,6 +221,7 @@ files:
|
|
220
221
|
- lib/quickeebooks/online/service/payment.rb
|
221
222
|
- lib/quickeebooks/online/service/service_base.rb
|
222
223
|
- lib/quickeebooks/online/service/sort.rb
|
224
|
+
- lib/quickeebooks/shared/service/access_token.rb
|
223
225
|
- lib/quickeebooks/shared/service/filter.rb
|
224
226
|
- lib/quickeebooks/version.rb
|
225
227
|
- lib/quickeebooks/windows/model/account.rb
|
@@ -258,6 +260,9 @@ files:
|
|
258
260
|
- lib/quickeebooks/windows/model/price.rb
|
259
261
|
- lib/quickeebooks/windows/model/purchase_cost.rb
|
260
262
|
- lib/quickeebooks/windows/model/rest_response.rb
|
263
|
+
- lib/quickeebooks/windows/model/sales_receipt.rb
|
264
|
+
- lib/quickeebooks/windows/model/sales_receipt_header.rb
|
265
|
+
- lib/quickeebooks/windows/model/sales_receipt_line_item.rb
|
261
266
|
- lib/quickeebooks/windows/model/sales_rep.rb
|
262
267
|
- lib/quickeebooks/windows/model/sales_tax.rb
|
263
268
|
- lib/quickeebooks/windows/model/ship_method.rb
|
@@ -268,6 +273,7 @@ files:
|
|
268
273
|
- lib/quickeebooks/windows/model/vendor_id.rb
|
269
274
|
- lib/quickeebooks/windows/model/vendor_reference.rb
|
270
275
|
- lib/quickeebooks/windows/model/web_site.rb
|
276
|
+
- lib/quickeebooks/windows/service/access_token.rb
|
271
277
|
- lib/quickeebooks/windows/service/account.rb
|
272
278
|
- lib/quickeebooks/windows/service/clazz.rb
|
273
279
|
- lib/quickeebooks/windows/service/company_meta_data.rb
|
@@ -277,6 +283,7 @@ files:
|
|
277
283
|
- lib/quickeebooks/windows/service/invoice.rb
|
278
284
|
- lib/quickeebooks/windows/service/item.rb
|
279
285
|
- lib/quickeebooks/windows/service/payment.rb
|
286
|
+
- lib/quickeebooks/windows/service/sales_receipt.rb
|
280
287
|
- lib/quickeebooks/windows/service/sales_rep.rb
|
281
288
|
- lib/quickeebooks/windows/service/sales_tax.rb
|
282
289
|
- lib/quickeebooks/windows/service/service_base.rb
|
@@ -299,6 +306,7 @@ files:
|
|
299
306
|
- spec/quickeebooks/online/services/invoice_spec.rb
|
300
307
|
- spec/quickeebooks/online/services/service_base_spec.rb
|
301
308
|
- spec/quickeebooks/online/services/sort_spec.rb
|
309
|
+
- spec/quickeebooks/shared/access_token_spec.rb
|
302
310
|
- spec/quickeebooks/windows/customer_spec.rb
|
303
311
|
- spec/quickeebooks/windows/services/class_spec.rb
|
304
312
|
- spec/quickeebooks/windows/services/company_meta_data_spec.rb
|
@@ -322,6 +330,12 @@ files:
|
|
322
330
|
- spec/xml/online/invoice.xml
|
323
331
|
- spec/xml/online/payment.xml
|
324
332
|
- spec/xml/online/user.xml
|
333
|
+
- spec/xml/shared/disconnect_invalid.xml
|
334
|
+
- spec/xml/shared/disconnect_success.xml
|
335
|
+
- spec/xml/shared/reconnect_error_expired.xml
|
336
|
+
- spec/xml/shared/reconnect_error_not_approved.xml
|
337
|
+
- spec/xml/shared/reconnect_error_out_of_bounds.xml
|
338
|
+
- spec/xml/shared/reconnect_success.xml
|
325
339
|
- spec/xml/windows/classes.xml
|
326
340
|
- spec/xml/windows/company_meta_data.xml
|
327
341
|
- spec/xml/windows/customer.xml
|