quickeebooks 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/Gemfile.lock +52 -0
- data/MIT-LICENSE +9 -0
- data/README.md +306 -0
- data/Rakefile +17 -0
- data/lib/quickeebooks.rb +89 -0
- data/lib/quickeebooks/online/model/account.rb +47 -0
- data/lib/quickeebooks/online/model/account_detail_type.rb +233 -0
- data/lib/quickeebooks/online/model/account_reference.rb +17 -0
- data/lib/quickeebooks/online/model/address.rb +42 -0
- data/lib/quickeebooks/online/model/customer.rb +66 -0
- data/lib/quickeebooks/online/model/customer_custom_field.rb +51 -0
- data/lib/quickeebooks/online/model/email.rb +24 -0
- data/lib/quickeebooks/online/model/intuit_type.rb +25 -0
- data/lib/quickeebooks/online/model/invoice.rb +50 -0
- data/lib/quickeebooks/online/model/invoice_header.rb +29 -0
- data/lib/quickeebooks/online/model/invoice_line_item.rb +22 -0
- data/lib/quickeebooks/online/model/item.rb +47 -0
- data/lib/quickeebooks/online/model/meta_data.rb +27 -0
- data/lib/quickeebooks/online/model/note.rb +11 -0
- data/lib/quickeebooks/online/model/open_balance.rb +11 -0
- data/lib/quickeebooks/online/model/phone.rb +12 -0
- data/lib/quickeebooks/online/model/price.rb +18 -0
- data/lib/quickeebooks/online/model/purchase_cost.rb +11 -0
- data/lib/quickeebooks/online/model/unit_price.rb +11 -0
- data/lib/quickeebooks/online/model/web_site.rb +16 -0
- data/lib/quickeebooks/online/service/account.rb +52 -0
- data/lib/quickeebooks/online/service/customer.rb +57 -0
- data/lib/quickeebooks/online/service/entitlement.rb +15 -0
- data/lib/quickeebooks/online/service/filter.rb +96 -0
- data/lib/quickeebooks/online/service/invoice.rb +50 -0
- data/lib/quickeebooks/online/service/item.rb +52 -0
- data/lib/quickeebooks/online/service/pagination.rb +19 -0
- data/lib/quickeebooks/online/service/service_base.rb +202 -0
- data/lib/quickeebooks/online/service/sort.rb +19 -0
- data/lib/quickeebooks/version.rb +5 -0
- data/lib/quickeebooks/windows/model/account.rb +67 -0
- data/lib/quickeebooks/windows/model/account_detail_type.rb +233 -0
- data/lib/quickeebooks/windows/model/account_reference.rb +19 -0
- data/lib/quickeebooks/windows/model/address.rb +36 -0
- data/lib/quickeebooks/windows/model/custom_field.rb +13 -0
- data/lib/quickeebooks/windows/model/customer.rb +109 -0
- data/lib/quickeebooks/windows/model/email.rb +44 -0
- data/lib/quickeebooks/windows/model/intuit_type.rb +17 -0
- data/lib/quickeebooks/windows/model/invoice.rb +44 -0
- data/lib/quickeebooks/windows/model/invoice_header.rb +65 -0
- data/lib/quickeebooks/windows/model/invoice_line_item.rb +38 -0
- data/lib/quickeebooks/windows/model/item.rb +84 -0
- data/lib/quickeebooks/windows/model/meta_data.rb +31 -0
- data/lib/quickeebooks/windows/model/note.rb +19 -0
- data/lib/quickeebooks/windows/model/open_balance.rb +11 -0
- data/lib/quickeebooks/windows/model/phone.rb +20 -0
- data/lib/quickeebooks/windows/model/price.rb +18 -0
- data/lib/quickeebooks/windows/model/purchase_cost.rb +12 -0
- data/lib/quickeebooks/windows/model/tax_line.rb +18 -0
- data/lib/quickeebooks/windows/model/unit_price.rb +12 -0
- data/lib/quickeebooks/windows/model/vendor_reference.rb +13 -0
- data/lib/quickeebooks/windows/model/web_site.rb +19 -0
- data/lib/quickeebooks/windows/service/account.rb +16 -0
- data/lib/quickeebooks/windows/service/customer.rb +16 -0
- data/lib/quickeebooks/windows/service/invoice.rb +27 -0
- data/lib/quickeebooks/windows/service/item.rb +18 -0
- data/lib/quickeebooks/windows/service/service_base.rb +176 -0
- data/quickeebooks.gemspec +27 -0
- data/spec/mocks/oauth_consumer_mock.rb +2 -0
- data/spec/quickeebooks/online/account_spec.rb +41 -0
- data/spec/quickeebooks/online/customer_spec.rb +46 -0
- data/spec/quickeebooks/online/invoice_spec.rb +15 -0
- data/spec/quickeebooks/online/services/account_spec.rb +84 -0
- data/spec/quickeebooks/online/services/customer_spec.rb +107 -0
- data/spec/quickeebooks/online/services/filter_spec.rb +43 -0
- data/spec/quickeebooks/online/services/service_base_spec.rb +30 -0
- data/spec/quickeebooks/online/services/sort_spec.rb +17 -0
- data/spec/quickeebooks/windows/customer_spec.rb +49 -0
- data/spec/quickeebooks_spec.rb +11 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/xml/online/account.xml +13 -0
- data/spec/xml/online/accounts.xml +108 -0
- data/spec/xml/online/customer.xml +63 -0
- data/spec/xml/online/customer2.xml +63 -0
- data/spec/xml/online/customers.xml +125 -0
- data/spec/xml/online/invoice.xml +33 -0
- data/spec/xml/online/user.xml +11 -0
- data/spec/xml/windows/customer.xml +56 -0
- data/spec/xml/windows/customers.xml +137 -0
- data/spec/xml/windows/http_401.xml +8 -0
- metadata +229 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
quickeebooks (0.0.1)
|
5
|
+
activemodel
|
6
|
+
nokogiri
|
7
|
+
oauth
|
8
|
+
roxml
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activemodel (3.2.1)
|
14
|
+
activesupport (= 3.2.1)
|
15
|
+
builder (~> 3.0.0)
|
16
|
+
activesupport (3.2.1)
|
17
|
+
i18n (~> 0.6)
|
18
|
+
multi_json (~> 1.0)
|
19
|
+
builder (3.0.0)
|
20
|
+
diff-lcs (1.1.3)
|
21
|
+
fakeweb (1.3.0)
|
22
|
+
i18n (0.6.0)
|
23
|
+
multi_json (1.1.0)
|
24
|
+
nokogiri (1.5.0)
|
25
|
+
oauth (0.4.5)
|
26
|
+
rake (0.9.2.2)
|
27
|
+
rcov (0.9.11)
|
28
|
+
roxml (3.3.1)
|
29
|
+
activesupport (>= 2.3.0)
|
30
|
+
nokogiri (>= 1.3.3)
|
31
|
+
rr (1.0.4)
|
32
|
+
rspec (2.0.1)
|
33
|
+
rspec-core (~> 2.0.1)
|
34
|
+
rspec-expectations (~> 2.0.1)
|
35
|
+
rspec-mocks (~> 2.0.1)
|
36
|
+
rspec-core (2.0.1)
|
37
|
+
rspec-expectations (2.0.1)
|
38
|
+
diff-lcs (>= 1.1.2)
|
39
|
+
rspec-mocks (2.0.1)
|
40
|
+
rspec-core (~> 2.0.1)
|
41
|
+
rspec-expectations (~> 2.0.1)
|
42
|
+
|
43
|
+
PLATFORMS
|
44
|
+
ruby
|
45
|
+
|
46
|
+
DEPENDENCIES
|
47
|
+
fakeweb
|
48
|
+
quickeebooks!
|
49
|
+
rake
|
50
|
+
rcov (~> 0.9.8)
|
51
|
+
rr (~> 1.0.2)
|
52
|
+
rspec (~> 2.0.0)
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2012
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,306 @@
|
|
1
|
+
# Quickeebooks
|
2
|
+
|
3
|
+
Integration with Quickbooks Online via the Intuit Data Services REST API.
|
4
|
+
|
5
|
+
This library communicates with the Quickbooks Data Services `v2` API, documented at:
|
6
|
+
|
7
|
+
[Data Services v2](https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services)
|
8
|
+
|
9
|
+
When Intuit finalizes the `v3` API I would like to move to that version as it appears to be better structured
|
10
|
+
and has `JSON` request/response formats, which should be easier to work with than XML.
|
11
|
+
|
12
|
+
## Requirements
|
13
|
+
|
14
|
+
This is being developed on Ruby 1.9.2. Other versions/VMs are untested but Ruby 1.8 should work in theory.
|
15
|
+
|
16
|
+
## Dependencies
|
17
|
+
|
18
|
+
Gems:
|
19
|
+
|
20
|
+
* `oauth`
|
21
|
+
* `roxml` : Workhorse for (de)serializing objects between Ruby & XML
|
22
|
+
* `nokogiri` : XML parsing
|
23
|
+
* `active_model` : For validations
|
24
|
+
|
25
|
+
## Getting Started
|
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:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
QB_KEY = "your-qb-key"
|
31
|
+
QB_SECRET = "your-qb-secret"
|
32
|
+
|
33
|
+
qb_oauth_consumer = OAuth::Consumer.new(QB_KEY, QB_SECRET, {
|
34
|
+
:site => "https://oauth.intuit.com",
|
35
|
+
:request_token_path => "/oauth/v1/get_request_token",
|
36
|
+
:authorize_url => "https://appcenter.intuit.com/Connect/Begin",
|
37
|
+
:access_token_path => "/oauth/v1/get_access_token"
|
38
|
+
})
|
39
|
+
|
40
|
+
oauth_client = OAuth::AccessToken.new(qb_oauth_consumer, access_token, access_secret)
|
41
|
+
```
|
42
|
+
|
43
|
+
## Quickbooks Online vs Windows
|
44
|
+
|
45
|
+
IDS provides 2 APIs, one for interacting with Quickbooks Online resources and one for Quickbooks Windows resources.
|
46
|
+
|
47
|
+
See: https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services
|
48
|
+
|
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.
|
50
|
+
|
51
|
+
For example:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# Instantiate a Online API
|
55
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
56
|
+
customer_service.list
|
57
|
+
|
58
|
+
# Instantiate a Windows API
|
59
|
+
customer_service = Quickeebooks::Windows::Service::Customer.new(oauth_client, realm_id)
|
60
|
+
customer_service.list
|
61
|
+
|
62
|
+
All of the documentation below is geared towards the Online flavor but unless noted one should be able to replace it with Windows.
|
63
|
+
|
64
|
+
Now we can initialize any of the `Service` clients:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
68
|
+
customer_service.list
|
69
|
+
|
70
|
+
# returns a `Collection` object
|
71
|
+
```
|
72
|
+
|
73
|
+
See *Retrieving Objects* for the complete docs on fetching collections.
|
74
|
+
|
75
|
+
Quickbooks API requires that all HTTP operations are performed against a client-specific "Base URL", as discussed here:
|
76
|
+
|
77
|
+
[Getting the Base URL](https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0400_QuickBooks_Online/0100_Calling_Data_Services/0010_Getting_the_Base_URL)
|
78
|
+
|
79
|
+
Quickeebooks will attempt to determine the base URL for the given OAuth client and Realm. This comes at the cost of the overhead of making that initial request. A customers Base URL should not change so if you know it ahead of time then you can specify it as the third argument to the service constructor. For example:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id, "https://qbo.intuit.com/qbo36")
|
83
|
+
```
|
84
|
+
|
85
|
+
## Retrieving Objects
|
86
|
+
|
87
|
+
Use a `Service` sub-class to fetch objects of that resource and specifically use the `list` method.
|
88
|
+
|
89
|
+
The signature of the `list` method is:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
list(filters = [], page = 1, per_page = 20, sort = nil, options = {})
|
93
|
+
```
|
94
|
+
|
95
|
+
Where `filters` is an array of `Filter` objects (see below). Pagination is set to page 1 and 20 results per page by default.
|
96
|
+
Pass a `Sort` object for any desired sorting or just let Intuit use the default sorting for that resource (see below for more sorting options).
|
97
|
+
|
98
|
+
Specify none of these to get the defaults:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id,)
|
102
|
+
# fetch all customers with default parameters (pagination, sorting, filtering)
|
103
|
+
customers = customer_service.list
|
104
|
+
```
|
105
|
+
|
106
|
+
Return result: a `Collection` instance with properties: `entries`, `current_page`, `count` which should be self-explanatory.
|
107
|
+
|
108
|
+
### Filtering (currently only supported in the Online API)
|
109
|
+
|
110
|
+
All filters in the Intuit documentation are supported: text, datetime, boolean.
|
111
|
+
|
112
|
+
Construct an instance of `Quickeebooks::Online::Service::Filter` with the type of filter, one of: `:text`, `:datetime`, `:boolean`.
|
113
|
+
|
114
|
+
Pass an array of `Quickeebooks::Online::Service::Filter` objects as the first argument to the Services `list` method and all filters will be applied.
|
115
|
+
|
116
|
+
#### Filtering on a text field
|
117
|
+
|
118
|
+
Specify a type of `:text` and your desired `:field` and a `:value` clause which will enforce an exact match.
|
119
|
+
|
120
|
+
Note: the Intuit API is case-INSENSITIVE.
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
Quickeebooks::Online::Service::Filter.new(:text, :field => 'FamilyName', :value => 'Richards')
|
124
|
+
```
|
125
|
+
|
126
|
+
#### Filtering on a Date/Time
|
127
|
+
|
128
|
+
Specify a type of `:datetime` and your desired `:field` than any combination of: `:before` and `:after`
|
129
|
+
|
130
|
+
Examples:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
# find all customers created after 2/15/2011
|
134
|
+
datetime = Time.mktime(2011, 2, 15)
|
135
|
+
Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'CreateTime', :after => datetime)
|
136
|
+
|
137
|
+
# find all customers created before 3/28/2011
|
138
|
+
datetime = Time.mktime(2011, 2, 28)
|
139
|
+
Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'CreateTime', :before => datetime)
|
140
|
+
|
141
|
+
# find all customers created between 1/1/2011 and 2/15/2011
|
142
|
+
after = Time.mktime(2011, 1, 1)
|
143
|
+
before = Time.mktime(2011, 2, 15
|
144
|
+
Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'CreateTime', :after => after, :before => before)
|
145
|
+
```
|
146
|
+
|
147
|
+
#### Filtering on a Boolean field
|
148
|
+
|
149
|
+
Specify a type of `:boolean` and your desired `:field` and a `:value` with either `true` or `false`
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
# find all customers and exclude jobs
|
153
|
+
Quickeebooks::Online::Service::Filter.new(:boolean, :field => 'IncludeJobs', :value => false)
|
154
|
+
```
|
155
|
+
|
156
|
+
#### Filtering on a Number
|
157
|
+
|
158
|
+
Specify a type of `:number` and an operator, one of: `:gt`, `:lt`, or `:eq`.
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
# find all customers and exclude jobs
|
162
|
+
Quickeebooks::Online::Service::Filter.new(:number, :field => 'Amount', :gt => 150)
|
163
|
+
```
|
164
|
+
|
165
|
+
Once you have created all of your `Filters` than just pass an array of them to any services `list` method and they will all be applied.
|
166
|
+
|
167
|
+
Example: find all Customers with a last name of 'Richards' who have been created before Feb 25, 2012:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
filters = []
|
171
|
+
filters << Quickeebooks::Online::Service::Filter.new(:text, :field => 'FamilyName', :value => 'Richards')
|
172
|
+
datetime = Time.mktime(2011, 2, 25)
|
173
|
+
filters << Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'CreateTime', :before => datetime)
|
174
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
175
|
+
customers = customer_service.list(filters)
|
176
|
+
```
|
177
|
+
## Sorting (currently only supported in the Online API)
|
178
|
+
|
179
|
+
Create an instance of `Quickeebooks::Service::Sort` where the first argument is the field and the second is the sorting direction/logic.
|
180
|
+
|
181
|
+
See [Sorting and Pagination](https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0400_QuickBooks_Online/0100_Calling_Data_Services/0030_Retrieving_Objects#Sorting) for the complete set of sorting options.
|
182
|
+
|
183
|
+
Example
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
sorter = Quickeebooks::Online::Service::Sort.new('FamilyName', 'AtoZ')
|
187
|
+
```
|
188
|
+
|
189
|
+
## Bringing it all together
|
190
|
+
|
191
|
+
Goal: fetch all customers with a last name of Smith starting at the first page with a per page size of 30, created between May and August of 2011 and sort by last name from A-to-Z.
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
filters = []
|
195
|
+
filters << Quickeebooks::Online::Service::Filter.new(:text, :field => 'FamilyName', :value => 'Smith')
|
196
|
+
|
197
|
+
d1 = Time.mktime(2011, 5, 1)
|
198
|
+
d2 = Time.mktime(2011, 8, 1)
|
199
|
+
filters << Quickeebooks::Online::Service::Filter.new(:datetime, :field => 'CreateTime', :after => d1, :before => d2)
|
200
|
+
|
201
|
+
sorter = Quickeebooks::Online::Service::Sort.new('FamilyName', 'AtoZ')
|
202
|
+
|
203
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
204
|
+
customers = customer_service.list(filters, 1, 30, sort)
|
205
|
+
|
206
|
+
# returns
|
207
|
+
|
208
|
+
customers.count
|
209
|
+
=> 67
|
210
|
+
|
211
|
+
customers.current_page
|
212
|
+
=> 1
|
213
|
+
|
214
|
+
customers.entries
|
215
|
+
=> [ #<Quickeebooks::Online::Model::Customer:0x007f8e29259770>, #<Quickeebooks::Online::Model::Customer:0x0078768202020>, ... ]
|
216
|
+
```
|
217
|
+
|
218
|
+
## Reading a single object
|
219
|
+
|
220
|
+
Use the `Service` instance to fetch an object by its id using the `fetch_by_id` method:
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
# fetch the Customer object with an id of 100
|
224
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
225
|
+
customer = customer_service.fetch_by_id(100)
|
226
|
+
customer.name
|
227
|
+
=> John Doe
|
228
|
+
```
|
229
|
+
|
230
|
+
## Writing Objects
|
231
|
+
|
232
|
+
Create or fetch an instance of a `Model` object and pass it to the corresponding service `create` or `update` method.
|
233
|
+
|
234
|
+
You will need make sure you supply all required fields for that Intuit object, so consult the documentation. For instance the documentation for a `Customer` object is at: [Intuit Customer Object](https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0400_QuickBooks_Online/Customer)
|
235
|
+
|
236
|
+
## Creating a single object
|
237
|
+
|
238
|
+
Pass an instance of your object to the `create` method on its related Service:
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
242
|
+
customer = Quickeebooks::Online::Model::Customer.new
|
243
|
+
customer.name = "Richard Parker"
|
244
|
+
customer.email = "richard@example.org"
|
245
|
+
customer_service.create(customer)
|
246
|
+
```
|
247
|
+
|
248
|
+
|
249
|
+
|
250
|
+
## Updating a single object
|
251
|
+
|
252
|
+
Pass an instance of your object to the `update` method on its related Service:
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
customer_service = Quickeebooks::Online::Service::Customer.new(oauth_client, realm_id)
|
256
|
+
customer = customer_service.fetch_by_id(100)
|
257
|
+
customer.name = "Richard Parker"
|
258
|
+
customer.email = "richard@example.org"
|
259
|
+
customer_service.update(customer)
|
260
|
+
```
|
261
|
+
|
262
|
+
# Services
|
263
|
+
|
264
|
+
All `Service` objects (`Quickeebooks::Online::Service::Customer`, `Quickeebooks::Online::Service::Account`, `Quickeebooks::Online::Service::Invoice`, etc) have a simple API for CRUD operations. Some service objects have additional functionality (for example the Invoice object can fetch a PDF representation of an invoice). See notes below for each service.
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
create(object)
|
268
|
+
update(object)
|
269
|
+
list()
|
270
|
+
fetch_by_id(object_id)
|
271
|
+
delete(object)
|
272
|
+
```
|
273
|
+
|
274
|
+
Current Services:
|
275
|
+
|
276
|
+
* Account
|
277
|
+
* Customer
|
278
|
+
* Invoice
|
279
|
+
* Item
|
280
|
+
|
281
|
+
|
282
|
+
## Invoice Service
|
283
|
+
|
284
|
+
The `Quickeebooks::Online::Service::Invoice` has the ability to retrieve an invoice as a PDF document:
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
invoice_as_pdf(invoice_id)
|
288
|
+
```
|
289
|
+
|
290
|
+
The `invoice_as_pdf` method returns a string representing the path to the PDF on the local disk. The method uses `ENV['TMPDIR']` to write the file to a temporary storage location. _Note:_ it is up to you the caller to remove or clean up the file when you are done.
|
291
|
+
|
292
|
+
## Author
|
293
|
+
|
294
|
+
Cody Caughlan
|
295
|
+
|
296
|
+
## License
|
297
|
+
|
298
|
+
The MIT License
|
299
|
+
|
300
|
+
Copyright (c) 2012
|
301
|
+
|
302
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
303
|
+
|
304
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
305
|
+
|
306
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler"
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
require "rake"
|
6
|
+
require "rspec"
|
7
|
+
require "rspec/core/rake_task"
|
8
|
+
|
9
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
10
|
+
require "quickeebooks"
|
11
|
+
|
12
|
+
task :default => :spec
|
13
|
+
|
14
|
+
desc "Run all specs"
|
15
|
+
Rspec::Core::RakeTask.new(:spec) do |t|
|
16
|
+
t.pattern = 'spec/**/*_spec.rb'
|
17
|
+
end
|
data/lib/quickeebooks.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'roxml'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'logger'
|
4
|
+
require 'active_model'
|
5
|
+
|
6
|
+
class InvalidModelException < Exception; end
|
7
|
+
|
8
|
+
module Quickeebooks
|
9
|
+
@@logger = nil
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
@@logger || Logger.new($stdout) # TODO: replace with a real log file
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.logger=(logger)
|
16
|
+
@@logger = logger
|
17
|
+
end
|
18
|
+
|
19
|
+
class Collection
|
20
|
+
attr_accessor :entries, :count, :current_page
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# monkey-path the to_xml method to add support for passing
|
26
|
+
# in a list of attributes that we want generated rather than the complete set
|
27
|
+
# This allows us to construct sub-object representations.
|
28
|
+
module ROXML
|
29
|
+
module InstanceMethods # :nodoc:
|
30
|
+
# Returns an XML object representing this object
|
31
|
+
def to_xml(params = {})
|
32
|
+
params[:fields] ||= []
|
33
|
+
params.reverse_merge!(:name => self.class.tag_name, :namespace => self.class.roxml_namespace)
|
34
|
+
params[:namespace] = nil if ['*', 'xmlns'].include?(params[:namespace])
|
35
|
+
XML.new_node([params[:namespace], params[:name]].compact.join(':')).tap do |root|
|
36
|
+
refs = (self.roxml_references.present? \
|
37
|
+
? self.roxml_references \
|
38
|
+
: self.class.roxml_attrs.map {|attr| attr.to_ref(self) })
|
39
|
+
|
40
|
+
if params[:fields].length > 0
|
41
|
+
refs.reject! { |r| !params[:fields].include?(r.name) }
|
42
|
+
end
|
43
|
+
refs.each do |ref|
|
44
|
+
value = ref.to_xml(self)
|
45
|
+
unless value.nil?
|
46
|
+
ref.update_xml(root, value)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#== Online
|
55
|
+
|
56
|
+
# Models
|
57
|
+
require 'quickeebooks/online/model/intuit_type'
|
58
|
+
require 'quickeebooks/online/model/customer'
|
59
|
+
require 'quickeebooks/online/model/account'
|
60
|
+
require 'quickeebooks/online/model/invoice'
|
61
|
+
require 'quickeebooks/online/model/invoice_header'
|
62
|
+
require 'quickeebooks/online/model/invoice_line_item'
|
63
|
+
require 'quickeebooks/online/model/item'
|
64
|
+
require 'quickeebooks/online/model/unit_price'
|
65
|
+
require 'quickeebooks/online/model/meta_data'
|
66
|
+
require 'quickeebooks/online/model/price'
|
67
|
+
require 'quickeebooks/online/model/account_reference'
|
68
|
+
|
69
|
+
# Services
|
70
|
+
require 'quickeebooks/online/service/filter'
|
71
|
+
require 'quickeebooks/online/service/pagination'
|
72
|
+
require 'quickeebooks/online/service/sort'
|
73
|
+
require 'quickeebooks/online/service/customer'
|
74
|
+
require 'quickeebooks/online/service/account'
|
75
|
+
require 'quickeebooks/online/service/invoice'
|
76
|
+
require 'quickeebooks/online/service/item'
|
77
|
+
require 'quickeebooks/online/service/entitlement'
|
78
|
+
|
79
|
+
#== Windows
|
80
|
+
require 'quickeebooks/windows/model/intuit_type'
|
81
|
+
require 'quickeebooks/windows/model/custom_field'
|
82
|
+
require 'quickeebooks/windows/model/price'
|
83
|
+
require 'quickeebooks/windows/model/customer'
|
84
|
+
require 'quickeebooks/windows/model/account'
|
85
|
+
require 'quickeebooks/windows/model/item'
|
86
|
+
require 'quickeebooks/windows/service/service_base'
|
87
|
+
require 'quickeebooks/windows/service/account'
|
88
|
+
require 'quickeebooks/windows/service/customer'
|
89
|
+
require 'quickeebooks/windows/service/item'
|