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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- quickeebooks (0.0.9)
4
+ quickeebooks (0.1.1)
5
5
  activemodel
6
6
  nokogiri
7
7
  oauth
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'
@@ -8,6 +8,7 @@ module Quickeebooks
8
8
 
9
9
  def to_xml(options = {})
10
10
  return "" if uri.to_s.empty?
11
+ super(options)
11
12
  end
12
13
 
13
14
  end
@@ -0,0 +1,11 @@
1
+ require 'quickeebooks/shared/service/access_token'
2
+
3
+ module Quickeebooks
4
+ module Online
5
+ module Service
6
+ class AccessToken < ServiceBase
7
+ include Quickeebooks::Shared::Service::AccessToken
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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: #{@value}"
47
+ clauses << "#{@field} :EQUALS: #{@eq}"
48
48
  end
49
49
  if @gt
50
- clauses << "#{@field} :GreaterThan: #{@value}"
50
+ clauses << "#{@field} :GreaterThan: #{@gt}"
51
51
  end
52
52
  if @lt
53
- clauses << "#{@field} :LessThan: #{@value}"
53
+ clauses << "#{@field} :LessThan: #{@lt}"
54
54
  end
55
55
  clauses.join(" :AND: ")
56
56
  end
@@ -1,5 +1,5 @@
1
1
  module Quickeebooks
2
2
 
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
 
5
5
  end
@@ -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 => 'CcExpireMn', :as => Integer
10
- xml_accessor :cc_expiration_year, :from => 'CcExpireYr', :as => Integer
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
@@ -0,0 +1,11 @@
1
+ require 'quickeebooks/shared/service/access_token'
2
+
3
+ module Quickeebooks
4
+ module Windows
5
+ module Service
6
+ class AccessToken < ServiceBase
7
+ include Quickeebooks::Shared::Service::AccessToken
8
+ end
9
+ end
10
+ end
11
+ 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("accounts", "Account", Quickeebooks::Windows::Model::Account, nil, filters, page, per_page, sort, options)
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
@@ -33,7 +33,9 @@
33
33
  <DeviceType>Mobile</DeviceType>
34
34
  <FreeFormNumber>(831) 334-0987</FreeFormNumber>
35
35
  </Phone>
36
- <WebSite/>
36
+ <WebSite>
37
+ <URI>http://blah.com</URI>
38
+ </WebSite>
37
39
  <Email>
38
40
  <Address>johndoe@gmail.com</Address>
39
41
  </Email>
@@ -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.0
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