quickeebooks 0.0.8 → 0.0.9

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.8)
4
+ quickeebooks (0.0.9)
5
5
  activemodel
6
6
  nokogiri
7
7
  oauth
data/README.md CHANGED
@@ -22,22 +22,69 @@ Gems:
22
22
  * `nokogiri` : XML parsing
23
23
  * `active_model` : For validations
24
24
 
25
- ## Getting Started
25
+ ## Getting Started & Initiating Authentication Flow with Intuit
26
26
 
27
- This library assumes you already have an OAuth token and secret. You can then initialize your `OAuth Consumer` and create a `OAuth Client` via:
27
+ What follows is an example using Rails but the principles can be adapted to any other framework / pure Ruby.
28
+
29
+ Create a Rails initializer with:
28
30
 
29
31
  ```ruby
30
- QB_KEY = "your-qb-key"
31
- QB_SECRET = "your-qb-secret"
32
+ QB_KEY = "your apps Intuit App Key"
33
+ QB_SECRET = "your apps Intuit Secret Key"
32
34
 
33
- qb_oauth_consumer = OAuth::Consumer.new(QB_KEY, QB_SECRET, {
35
+ $qb_oauth_consumer = OAuth::Consumer.new(QB_KEY, QB_SECRET, {
34
36
  :site => "https://oauth.intuit.com",
35
37
  :request_token_path => "/oauth/v1/get_request_token",
36
38
  :authorize_url => "https://appcenter.intuit.com/Connect/Begin",
37
39
  :access_token_path => "/oauth/v1/get_access_token"
38
40
  })
41
+ ```
42
+
43
+ To start the authentication flow with Intuit you include the Intuit Javascript and on a page of your choosing you present the "Connect to Quickbooks" button by including this XHTML:
44
+
45
+
46
+ ```HTML
47
+ <!-- somewhere in your document include the Javascript -->
48
+ <script type="text/javascript" src="https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js"></script>
49
+
50
+ <!-- configure the Intuit object: 'grantUrl' is a URL in your application which kicks off the flow, see below -->
51
+ <script>
52
+ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '/path/to/your-flow-start'});
53
+ </script>
54
+
55
+ <!-- this will display a button that the user clicks to start the flow -->
56
+ <ipp:connectToIntuit></ipp:connectToIntuit>
57
+ ```
58
+
59
+ Your Controller action (the `grantUrl` above) should look like this:
60
+
61
+ ```ruby
62
+ def authenticate
63
+ callback = quickbooks_oauth_callback_url
64
+ token = $qb_oauth_consumer.get_request_token(:oauth_callback => callback)
65
+ session[:qb_request_token] = token
66
+ redirect_to("https://appcenter.intuit.com/Connect/Begin?oauth_token=#{token.token}") and return
67
+ end
68
+ ```
69
+
70
+ Where `quickbooks_oauth_callback_url` is the absolute URL of your application that Intuit should send the user when authentication succeeeds. That action should look like:
71
+
72
+ ```ruby
73
+ def oauth_callback
74
+ at = session[:qb_request_token].get_access_token(:oauth_verifier => params[:oauth_verifier])
75
+ token = at.token
76
+ secret = at.secret
77
+ realm_id = params['realmId']
78
+ # store the token, secret & RealmID somewhere for this user, you will need all 3 to work with Quickeebooks
79
+ end
80
+ ```
39
81
 
40
- oauth_client = OAuth::AccessToken.new(qb_oauth_consumer, access_token, access_secret)
82
+ ## Creating an OAuth Access Token
83
+
84
+ Once you have your users OAuth Token & Secret you can initialize your `OAuth Consumer` and create a `OAuth Client` using the `$qb_oauth_consumer` you created earlier in your Rails initializer:
85
+
86
+ ```ruby
87
+ oauth_client = OAuth::AccessToken.new($qb_oauth_consumer, access_token, access_secret)
41
88
  ```
42
89
 
43
90
  ## Quickbooks Online vs Windows
@@ -46,17 +93,21 @@ IDS provides 2 APIs, one for interacting with Quickbooks Online resources and on
46
93
 
47
94
  See: https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services
48
95
 
49
- As of this time Quickeebooks has a little more features for Online API vs Windows API. Ultimately the Quickeebooks API should be the same and its just a matter of instantiating the correct classes.
96
+ You will need to be aware of which flavor of the API you want to invoke.
50
97
 
51
98
  For example:
52
99
 
53
100
  ```ruby
54
101
  # Instantiate a Online API
55
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
102
+ customer_service = Quickeebooks::Online::Service::Customer.new
103
+ customer_service.access_token = oauth_client
104
+ customer_service.realm_id = realm_id
56
105
  customer_service.list
57
106
 
58
107
  # Instantiate a Windows API
59
108
  customer_service = Quickeebooks::Windows::Service::Customer.new(oauth_client, realm_id)
109
+ customer_service.access_token = oauth_client
110
+ customer_service.realm_id = realm_id
60
111
  customer_service.list
61
112
  ```
62
113
 
@@ -65,7 +116,10 @@ All of the documentation below is geared towards the Online flavor but unless no
65
116
  Now we can initialize any of the `Service` clients:
66
117
 
67
118
  ```ruby
68
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
119
+ customer_service = Quickeebooks::Online::Service::Customer.new
120
+ customer_service.access_token = oauth_client
121
+ customer_service.realm_id = realm_id
122
+ customer_service.list
69
123
  customer_service.list
70
124
 
71
125
  # returns a `Collection` object
@@ -99,7 +153,11 @@ Pass a `Sort` object for any desired sorting or just let Intuit use the default
99
153
  Specify none of these to get the defaults:
100
154
 
101
155
  ```ruby
102
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id,)
156
+ customer_service = Quickeebooks::Online::Service::Customer.new
157
+ customer_service.access_token = oauth_client
158
+ customer_service.realm_id = realm_id
159
+ customer_service.list
160
+
103
161
  # fetch all customers with default parameters (pagination, sorting, filtering)
104
162
  customers = customer_service.list
105
163
  ```
@@ -172,7 +230,11 @@ filters = []
172
230
  filters << Quickeebooks::Online::Service::Filter.new(:text, :field => 'FamilyName', :value => 'Richards')
173
231
  datetime = Time.mktime(2011, 2, 25)
174
232
  filters << Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'CreateTime', :before => datetime)
175
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
233
+ customer_service = Quickeebooks::Online::Service::Customer.new
234
+ customer_service.access_token = oauth_client
235
+ customer_service.realm_id = realm_id
236
+ customer_service.list
237
+
176
238
  customers = customer_service.list(filters)
177
239
  ```
178
240
  ## Sorting (currently only supported in the Online API)
@@ -201,7 +263,11 @@ filters << Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'Creat
201
263
 
202
264
  sorter = Quickeebooks::Online::Service::Sort.new('FamilyName', 'AtoZ')
203
265
 
204
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
266
+ customer_service = Quickeebooks::Online::Service::Customer.new
267
+ customer_service.access_token = oauth_client
268
+ customer_service.realm_id = realm_id
269
+ customer_service.list
270
+
205
271
  customers = customer_service.list(filters, 1, 30, sort)
206
272
 
207
273
  # returns
@@ -222,7 +288,11 @@ Use the `Service` instance to fetch an object by its id using the `fetch_by_id`
222
288
 
223
289
  ```ruby
224
290
  # fetch the Customer object with an id of 100
225
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
291
+ customer_service = Quickeebooks::Online::Service::Customer.new
292
+ customer_service.access_token = oauth_client
293
+ customer_service.realm_id = realm_id
294
+ customer_service.list
295
+
226
296
  customer = customer_service.fetch_by_id(100)
227
297
  customer.name
228
298
  => John Doe
@@ -239,7 +309,11 @@ You will need make sure you supply all required fields for that Intuit object, s
239
309
  Pass an instance of your object to the `create` method on its related Service:
240
310
 
241
311
  ```ruby
242
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
312
+ customer_service = Quickeebooks::Online::Service::Customer.new
313
+ customer_service.access_token = oauth_client
314
+ customer_service.realm_id = realm_id
315
+ customer_service.list
316
+
243
317
  customer = Quickeebooks::Online::Model::Customer.new
244
318
  customer.name = "Richard Parker"
245
319
  customer.email = "richard@example.org"
@@ -253,7 +327,11 @@ customer_service.create(customer)
253
327
  Pass an instance of your object to the `update` method on its related Service:
254
328
 
255
329
  ```ruby
256
- customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
330
+ customer_service = Quickeebooks::Online::Service::Customer.new
331
+ customer_service.access_token = oauth_client
332
+ customer_service.realm_id = realm_id
333
+ customer_service.list
334
+
257
335
  customer = customer_service.fetch_by_id(100)
258
336
  customer.name = "Richard Parker"
259
337
  customer.email = "richard@example.org"
@@ -17,6 +17,7 @@ module Quickeebooks
17
17
  xml_accessor :sales_tax_code_name, :from => 'SalesTaxCodeName'
18
18
  xml_accessor :sub_total_amount, :from => 'SubTotalAmt', :as => Float
19
19
  xml_accessor :tax_rate, :from => 'TaxRate', :as => Float
20
+ xml_accessor :tax_amount, :from => 'TaxAmt', :as => Float
20
21
  xml_accessor :balance, :from => 'Balance', :as => Float
21
22
  xml_accessor :total_amount, :from => 'TotalAmt', :as => Float
22
23
  xml_accessor :due_date, :from => 'DueDate', :as => Time
@@ -1,5 +1,5 @@
1
1
  module Quickeebooks
2
2
 
3
- VERSION = "0.0.8"
3
+ VERSION = "0.0.9"
4
4
 
5
5
  end
@@ -15,8 +15,8 @@ module Quickeebooks
15
15
  xml_accessor :country_sub_division_code, :from => 'CountrySubDivisionCode'
16
16
  xml_accessor :postal_code, :from => 'PostalCode'
17
17
  xml_accessor :postal_code_suffix, :from => 'PostalCodeSuffix'
18
- xml_accessor :tag, :from => 'Tag'
19
18
  xml_accessor :default, :from => 'Default'
19
+ xml_accessor :tag, :from => 'Tag'
20
20
 
21
21
  def zip
22
22
  postal_code
@@ -34,9 +34,9 @@ module Quickeebooks
34
34
  xml_accessor :type_of, :from => 'TypeOf'
35
35
  xml_accessor :name, :from => 'Name'
36
36
  xml_accessor :addresses, :from => 'Address', :as => [Quickeebooks::Windows::Model::Address]
37
- xml_accessor :email, :from => 'Email', :as => Quickeebooks::Windows::Model::Email
38
37
  xml_accessor :phones, :from => 'Phone', :as => [Quickeebooks::Windows::Model::Phone]
39
38
  xml_accessor :web_site, :from => 'WebSite', :as => Quickeebooks::Windows::Model::WebSite
39
+ xml_accessor :email, :from => 'Email', :as => Quickeebooks::Windows::Model::Email
40
40
  xml_accessor :title, :from => 'Title'
41
41
  xml_accessor :given_name, :from => 'GivenName'
42
42
  xml_accessor :middle_name, :from => 'MiddleName'
@@ -7,8 +7,8 @@ module Quickeebooks
7
7
  xml_accessor :id, :from => 'Id'
8
8
  xml_accessor :device_type, :from => 'DeviceType'
9
9
  xml_accessor :free_form_number, :from => 'FreeFormNumber'
10
- xml_accessor :tag, :from => 'Tag'
11
10
  xml_accessor :default, :from => 'Default'
11
+ xml_accessor :tag, :from => 'Tag'
12
12
 
13
13
  def default?
14
14
  default == "true"
@@ -32,7 +32,41 @@ module Quickeebooks
32
32
  </Add>
33
33
  XML
34
34
  perform_write(Quickeebooks::Windows::Model::Customer, xml)
35
+ end
36
+
37
+ def update(customer)
38
+ # XML is a wrapped 'object' where the type is specified as an attribute
39
+ # <Object xsi:type="Invoice">
40
+
41
+ # Intuit requires that some fields are unset / do not exist.
42
+ customer.meta_data = nil
43
+ customer.external_key = nil
44
+
45
+ # unset Id fields in addresses, phones, email
46
+ if customer.addresses
47
+ customer.addresses.each {|address| address.id = nil }
48
+ end
49
+ if customer.email
50
+ customer.email.id = nil
51
+ end
52
+
53
+ if customer.phones
54
+ customer.phones.each {|phone| phone.id = nil }
55
+ end
56
+
57
+ if customer.web_site
58
+ customer.web_site.id = nil
59
+ end
35
60
 
61
+ xml_node = customer.to_xml(:name => 'Object')
62
+ xml_node.set_attribute('xsi:type', 'Customer')
63
+ xml = <<-XML
64
+ <Mod 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">
65
+ <ExternalRealmId>#{self.realm_id}</ExternalRealmId>
66
+ #{xml_node}
67
+ </Mod>
68
+ XML
69
+ perform_write(Quickeebooks::Windows::Model::Customer, xml)
36
70
  end
37
71
 
38
72
  end
@@ -153,6 +153,26 @@ describe "Quickeebooks::Windows::Service::Customer" do
153
153
  create_response.success.party_role_ref.id.value.should == "6762304"
154
154
  create_response.success.request_name.should == "CustomerAdd"
155
155
  end
156
+
157
+ it "can update a customer name" do
158
+ customer_xml = File.read(File.dirname(__FILE__) + "/../../../xml/windows/customer.xml")
159
+ update_response_xml = File.read(File.dirname(__FILE__) + "/../../../xml/windows/customer_update_success.xml")
160
+ service = Quickeebooks::Windows::Service::Customer.new
161
+ model = Quickeebooks::Windows::Model::Customer
162
+ customer = model.from_xml(customer_xml)
163
+ customer.name.should == "Wine House"
164
+
165
+ service.access_token = @oauth
166
+ service.realm_id = @realm_id
167
+ FakeWeb.register_uri(:post, service.url_for_resource(model::REST_RESOURCE), :status => ["200", "OK"], :body => update_response_xml)
168
+
169
+ # change the name
170
+ customer.name = "Acme Cafe"
171
+ update_response = service.update(customer)
172
+ update_response.success?.should == true
173
+ update_response.success.party_role_ref.id.value.should == "6762304"
174
+ update_response.success.request_name.should == "CustomerMod"
175
+ end
156
176
 
157
177
 
158
178
  end
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0"?>
2
+ <RestResponse xmlns="http://www.intuit.com/sb/cdm/v2">
3
+ <Success RequestId="1b405391016149c593c005e45700dd01">
4
+ <PartyRoleRef>
5
+ <Id idDomain="NG">6762304</Id>
6
+ <SyncToken>7</SyncToken>
7
+ <LastUpdatedTime>2012-11-29T01:01:47Z</LastUpdatedTime>
8
+ <PartyReferenceId idDomain="NG">6170150</PartyReferenceId>
9
+ </PartyRoleRef>
10
+ <RequestName>CustomerMod</RequestName>
11
+ <ProcessedTime>2012-11-29T01:01:47Z</ProcessedTime>
12
+ </Success>
13
+ </RestResponse>
@@ -3,6 +3,7 @@ require 'oauth'
3
3
  $: << File.expand_path('./lib')
4
4
  require 'quickeebooks'
5
5
 
6
+ # attached to "Vinosmith.qbw" in Quickbooks Simple Start 2010
6
7
  consumer_key = 'qyprdL8NUDMYcCzwp8ea9KbIhaMSRk'
7
8
  consumer_secret = 'FcE5kihBYMVQGvX9UNYMxsrM8mP7bfuxc36PLhJB'
8
9
  qb_oauth_consumer = OAuth::Consumer.new(consumer_key, consumer_secret, {
@@ -22,6 +23,22 @@ service = Quickeebooks::Windows::Service::Customer.new
22
23
  service.access_token = oauth
23
24
  service.realm_id = realm_id
24
25
 
26
+ customer = service.fetch_by_id(1)
27
+ puts customer.name
28
+ if customer.notes
29
+ customer.notes.each { |note| puts note.content }
30
+ end
31
+ # UPDATE it
32
+ customer.name = "Cody 22 TEST"
33
+
34
+ customer.meta_data = nil
35
+ customer.external_key = nil
36
+
37
+ response = service.update(customer)
38
+ #puts response.inspect
39
+
40
+ #puts service.list
41
+ =begin
25
42
  customer = Quickeebooks::Windows::Model::Customer.new
26
43
  customer.type_of = "Person"
27
44
  customer.name = "Cody Test-#{Time.now.to_i}"
@@ -38,4 +55,5 @@ billing_address.postal_code = "94117"
38
55
  billing_address.country = "USA"
39
56
  customer.address = billing_address
40
57
  result = service.create(customer)
41
- puts result.inspect
58
+ puts result.inspect
59
+ =end
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.0.8
4
+ version: 0.0.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-20 00:00:00.000000000 Z
12
+ date: 2012-11-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: roxml
@@ -325,6 +325,7 @@ files:
325
325
  - spec/xml/windows/company_meta_data.xml
326
326
  - spec/xml/windows/customer.xml
327
327
  - spec/xml/windows/customer_create_success.xml
328
+ - spec/xml/windows/customer_update_success.xml
328
329
  - spec/xml/windows/customers.xml
329
330
  - spec/xml/windows/fetch_customer_by_id.xml
330
331
  - spec/xml/windows/http_401.xml