quickbooks-ruby-oauth2 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/quickbooks/faraday/middleware/gzip.rb +72 -0
- data/lib/quickbooks/model/access_token_response.rb +29 -0
- data/lib/quickbooks/model/account.rb +78 -0
- data/lib/quickbooks/model/account_based_expense_line_detail.rb +15 -0
- data/lib/quickbooks/model/attachable.rb +33 -0
- data/lib/quickbooks/model/attachable_ref.rb +22 -0
- data/lib/quickbooks/model/base_model.rb +120 -0
- data/lib/quickbooks/model/base_model_json.rb +16 -0
- data/lib/quickbooks/model/base_reference.rb +23 -0
- data/lib/quickbooks/model/batch_request.rb +45 -0
- data/lib/quickbooks/model/batch_response.rb +33 -0
- data/lib/quickbooks/model/bill.rb +45 -0
- data/lib/quickbooks/model/bill_line_item.rb +42 -0
- data/lib/quickbooks/model/bill_payment.rb +40 -0
- data/lib/quickbooks/model/bill_payment_check.rb +12 -0
- data/lib/quickbooks/model/bill_payment_credit_card.rb +10 -0
- data/lib/quickbooks/model/bill_payment_line_item.rb +21 -0
- data/lib/quickbooks/model/budget.rb +27 -0
- data/lib/quickbooks/model/budget_line_item.rb +15 -0
- data/lib/quickbooks/model/change_data_capture.rb +42 -0
- data/lib/quickbooks/model/change_model.rb +10 -0
- data/lib/quickbooks/model/check_payment.rb +11 -0
- data/lib/quickbooks/model/class.rb +31 -0
- data/lib/quickbooks/model/company_info.rb +69 -0
- data/lib/quickbooks/model/credit_card_payment.rb +17 -0
- data/lib/quickbooks/model/credit_memo.rb +59 -0
- data/lib/quickbooks/model/credit_memo_change.rb +8 -0
- data/lib/quickbooks/model/custom_field.rb +13 -0
- data/lib/quickbooks/model/customer.rb +76 -0
- data/lib/quickbooks/model/customer_change.rb +8 -0
- data/lib/quickbooks/model/definition.rb +46 -0
- data/lib/quickbooks/model/delivery_info.rb +8 -0
- data/lib/quickbooks/model/department.rb +31 -0
- data/lib/quickbooks/model/deposit.rb +44 -0
- data/lib/quickbooks/model/deposit_line_detail.rb +17 -0
- data/lib/quickbooks/model/deposit_line_item.rb +35 -0
- data/lib/quickbooks/model/description_line_detail.rb +7 -0
- data/lib/quickbooks/model/discount_line_detail.rb +15 -0
- data/lib/quickbooks/model/discount_override.rb +13 -0
- data/lib/quickbooks/model/document_numbering.rb +18 -0
- data/lib/quickbooks/model/effective_tax_rate.rb +15 -0
- data/lib/quickbooks/model/email_address.rb +19 -0
- data/lib/quickbooks/model/employee.rb +47 -0
- data/lib/quickbooks/model/entity.rb +16 -0
- data/lib/quickbooks/model/entity_ref.rb +8 -0
- data/lib/quickbooks/model/estimate.rb +76 -0
- data/lib/quickbooks/model/exchange_rate.rb +23 -0
- data/lib/quickbooks/model/fault.rb +16 -0
- data/lib/quickbooks/model/global_tax_calculation.rb +13 -0
- data/lib/quickbooks/model/group_line_detail.rb +13 -0
- data/lib/quickbooks/model/has_line_items.rb +14 -0
- data/lib/quickbooks/model/invoice.rb +107 -0
- data/lib/quickbooks/model/invoice_change.rb +9 -0
- data/lib/quickbooks/model/invoice_group_line_detail.rb +14 -0
- data/lib/quickbooks/model/invoice_line_item.rb +88 -0
- data/lib/quickbooks/model/item.rb +87 -0
- data/lib/quickbooks/model/item_based_expense_line_detail.rb +20 -0
- data/lib/quickbooks/model/item_change.rb +8 -0
- data/lib/quickbooks/model/item_group_detail.rb +9 -0
- data/lib/quickbooks/model/item_group_line.rb +20 -0
- data/lib/quickbooks/model/journal_entry.rb +36 -0
- data/lib/quickbooks/model/journal_entry_line_detail.rb +27 -0
- data/lib/quickbooks/model/line.rb +95 -0
- data/lib/quickbooks/model/line_ex.rb +9 -0
- data/lib/quickbooks/model/linked_transaction.rb +9 -0
- data/lib/quickbooks/model/markup_info.rb +12 -0
- data/lib/quickbooks/model/meta_data.rb +24 -0
- data/lib/quickbooks/model/name_value.rb +8 -0
- data/lib/quickbooks/model/other_contact_info.rb +8 -0
- data/lib/quickbooks/model/payment.rb +43 -0
- data/lib/quickbooks/model/payment_change.rb +8 -0
- data/lib/quickbooks/model/payment_line_detail.rb +12 -0
- data/lib/quickbooks/model/payment_method.rb +25 -0
- data/lib/quickbooks/model/physical_address.rb +40 -0
- data/lib/quickbooks/model/preferences.rb +49 -0
- data/lib/quickbooks/model/purchase.rb +57 -0
- data/lib/quickbooks/model/purchase_line_item.rb +44 -0
- data/lib/quickbooks/model/purchase_order.rb +50 -0
- data/lib/quickbooks/model/purchase_tax_rate_list.rb +11 -0
- data/lib/quickbooks/model/refund_receipt.rb +62 -0
- data/lib/quickbooks/model/refund_receipt_change.rb +8 -0
- data/lib/quickbooks/model/report.rb +52 -0
- data/lib/quickbooks/model/sales_item_line_detail.rb +16 -0
- data/lib/quickbooks/model/sales_receipt.rb +65 -0
- data/lib/quickbooks/model/sales_tax_rate_list.rb +11 -0
- data/lib/quickbooks/model/sub_total_line_detail.rb +13 -0
- data/lib/quickbooks/model/tax_agency.rb +18 -0
- data/lib/quickbooks/model/tax_code.rb +21 -0
- data/lib/quickbooks/model/tax_line.rb +15 -0
- data/lib/quickbooks/model/tax_line_detail.rb +16 -0
- data/lib/quickbooks/model/tax_rate.rb +28 -0
- data/lib/quickbooks/model/tax_rate_detail.rb +15 -0
- data/lib/quickbooks/model/tax_rate_detail_line.rb +23 -0
- data/lib/quickbooks/model/tax_service.rb +52 -0
- data/lib/quickbooks/model/telephone_number.rb +13 -0
- data/lib/quickbooks/model/term.rb +28 -0
- data/lib/quickbooks/model/time_activity.rb +79 -0
- data/lib/quickbooks/model/transaction_tax_detail.rb +12 -0
- data/lib/quickbooks/model/transfer.rb +21 -0
- data/lib/quickbooks/model/upload.rb +35 -0
- data/lib/quickbooks/model/validator.rb +10 -0
- data/lib/quickbooks/model/vendor.rb +53 -0
- data/lib/quickbooks/model/vendor_change.rb +8 -0
- data/lib/quickbooks/model/vendor_credit.rb +40 -0
- data/lib/quickbooks/model/web_site_address.rb +16 -0
- data/lib/quickbooks/service/access_token.rb +38 -0
- data/lib/quickbooks/service/account.rb +17 -0
- data/lib/quickbooks/service/attachable.rb +12 -0
- data/lib/quickbooks/service/base_service.rb +445 -0
- data/lib/quickbooks/service/base_service_json.rb +39 -0
- data/lib/quickbooks/service/batch.rb +11 -0
- data/lib/quickbooks/service/bill.rb +16 -0
- data/lib/quickbooks/service/bill_payment.rb +16 -0
- data/lib/quickbooks/service/budget.rb +12 -0
- data/lib/quickbooks/service/change_data_capture.rb +24 -0
- data/lib/quickbooks/service/change_service.rb +28 -0
- data/lib/quickbooks/service/class.rb +23 -0
- data/lib/quickbooks/service/company_info.rb +12 -0
- data/lib/quickbooks/service/credit_memo.rb +16 -0
- data/lib/quickbooks/service/credit_memo_change.rb +16 -0
- data/lib/quickbooks/service/customer.rb +18 -0
- data/lib/quickbooks/service/customer_change.rb +16 -0
- data/lib/quickbooks/service/department.rb +23 -0
- data/lib/quickbooks/service/deposit.rb +16 -0
- data/lib/quickbooks/service/employee.rb +24 -0
- data/lib/quickbooks/service/estimate.rb +22 -0
- data/lib/quickbooks/service/exchange_rate.rb +25 -0
- data/lib/quickbooks/service/invoice.rb +45 -0
- data/lib/quickbooks/service/invoice_change.rb +16 -0
- data/lib/quickbooks/service/item.rb +32 -0
- data/lib/quickbooks/service/item_change.rb +16 -0
- data/lib/quickbooks/service/journal_entry.rb +16 -0
- data/lib/quickbooks/service/payment.rb +29 -0
- data/lib/quickbooks/service/payment_change.rb +16 -0
- data/lib/quickbooks/service/payment_method.rb +30 -0
- data/lib/quickbooks/service/preferences.rb +12 -0
- data/lib/quickbooks/service/purchase.rb +16 -0
- data/lib/quickbooks/service/purchase_order.rb +16 -0
- data/lib/quickbooks/service/refund_receipt.rb +16 -0
- data/lib/quickbooks/service/refund_receipt_change.rb +16 -0
- data/lib/quickbooks/service/reports.rb +33 -0
- data/lib/quickbooks/service/responses/methods.rb +17 -0
- data/lib/quickbooks/service/responses/oauth1_http_response.rb +42 -0
- data/lib/quickbooks/service/responses/oauth2_http_response.rb +43 -0
- data/lib/quickbooks/service/responses/oauth_http_response.rb +21 -0
- data/lib/quickbooks/service/sales_receipt.rb +46 -0
- data/lib/quickbooks/service/service_crud.rb +75 -0
- data/lib/quickbooks/service/service_crud_json.rb +31 -0
- data/lib/quickbooks/service/tax_agency.rb +12 -0
- data/lib/quickbooks/service/tax_code.rb +12 -0
- data/lib/quickbooks/service/tax_rate.rb +12 -0
- data/lib/quickbooks/service/tax_service.rb +11 -0
- data/lib/quickbooks/service/term.rb +17 -0
- data/lib/quickbooks/service/time_activity.rb +16 -0
- data/lib/quickbooks/service/transfer.rb +16 -0
- data/lib/quickbooks/service/upload.rb +39 -0
- data/lib/quickbooks/service/vendor.rb +24 -0
- data/lib/quickbooks/service/vendor_change.rb +16 -0
- data/lib/quickbooks/service/vendor_credit.rb +16 -0
- data/lib/quickbooks/util/collection.rb +18 -0
- data/lib/quickbooks/util/http_encoding_helper.rb +54 -0
- data/lib/quickbooks/util/logging.rb +19 -0
- data/lib/quickbooks/util/multipart.rb +85 -0
- data/lib/quickbooks/util/name_entity.rb +85 -0
- data/lib/quickbooks/util/query_builder.rb +35 -0
- data/lib/quickbooks/version.rb +5 -0
- data/lib/quickbooks-ruby.rb +255 -0
- metadata +378 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Service
|
3
|
+
module Responses
|
4
|
+
|
5
|
+
# This class just proxies and returns a wrapped response so that callers
|
6
|
+
# can invoke a common interface
|
7
|
+
class OAuthHttpResponse
|
8
|
+
|
9
|
+
def self.wrap(response)
|
10
|
+
if response.is_a?(OAuth2::Response)
|
11
|
+
Quickbooks::Service::Responses::OAuth2HttpResponse.new(response)
|
12
|
+
else
|
13
|
+
Quickbooks::Service::Responses::OAuth1HttpResponse.new(response)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Service
|
3
|
+
class SalesReceipt < BaseService
|
4
|
+
|
5
|
+
def delete(sales_receipt)
|
6
|
+
delete_by_query_string(sales_receipt)
|
7
|
+
end
|
8
|
+
|
9
|
+
def pdf(sales_receipt)
|
10
|
+
url = "#{url_for_resource(model::REST_RESOURCE)}/#{sales_receipt.id}/pdf"
|
11
|
+
response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
|
12
|
+
response.plain_body
|
13
|
+
end
|
14
|
+
|
15
|
+
def send(sr, email_address=nil)
|
16
|
+
query = email_address.present? ? "?sendTo=#{email_address}" : ""
|
17
|
+
url = "#{url_for_resource(model::REST_RESOURCE)}/#{sr.id}/send#{query}"
|
18
|
+
response = do_http_post(url,{})
|
19
|
+
if response.code.to_i == 200
|
20
|
+
model.from_xml(parse_singular_entity_response(model, response.plain_body))
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def void(sales_receipt, options = {})
|
27
|
+
raise Quickbooks::InvalidModelException.new(sales_receipt.errors.full_messages.join(',')) unless sales_receipt.valid?
|
28
|
+
xml = sales_receipt.to_xml_ns(options)
|
29
|
+
url = "#{url_for_resource(model::REST_RESOURCE)}?include=void"
|
30
|
+
|
31
|
+
response = do_http_post(url, valid_xml_document(xml), {})
|
32
|
+
if response.code.to_i == 200
|
33
|
+
model.from_xml(parse_singular_entity_response(model, response.plain_body))
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def model
|
42
|
+
Quickbooks::Model::SalesReceipt
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Service
|
3
|
+
module ServiceCrud
|
4
|
+
|
5
|
+
def query(object_query = nil, options = {})
|
6
|
+
fetch_collection(object_query, model, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
# fetch all records, returns an array of models
|
10
|
+
def all(object_query=nil, options={})
|
11
|
+
collection = []
|
12
|
+
self.query_in_batches(object_query, options) do |batch|
|
13
|
+
collection << batch.entries
|
14
|
+
end
|
15
|
+
collection.flatten
|
16
|
+
end
|
17
|
+
|
18
|
+
def query_in_batches(object_query=nil, options={})
|
19
|
+
page = 0
|
20
|
+
per_page = options.delete(:per_page) || 1_000
|
21
|
+
begin
|
22
|
+
page += 1
|
23
|
+
results = query(object_query, page: page, per_page: per_page)
|
24
|
+
yield results if results.count > 0
|
25
|
+
end until results.count < per_page
|
26
|
+
end
|
27
|
+
|
28
|
+
def exists?(field, selector, options={})
|
29
|
+
find_by(field, selector, options).count > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_by(field, selector, options={})
|
33
|
+
if field.class == Symbol
|
34
|
+
field = field.to_s.camelcase
|
35
|
+
end
|
36
|
+
q = "select * from %s where %s = '%s'" % [model.resource_for_singular, field, selector]
|
37
|
+
self.query(q, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def fetch_by_id(id, params = {})
|
41
|
+
url = "#{url_for_resource(model.resource_for_singular)}/#{id}"
|
42
|
+
fetch_object(model, url, params)
|
43
|
+
end
|
44
|
+
|
45
|
+
def create(entity, options = {})
|
46
|
+
raise Quickbooks::InvalidModelException.new(entity.errors.full_messages.join(',')) unless entity.valid?
|
47
|
+
xml = entity.to_xml_ns(options)
|
48
|
+
|
49
|
+
response = do_http_post(url_for_resource(model.resource_for_singular), valid_xml_document(xml), options[:query])
|
50
|
+
if response.code.to_i == 200
|
51
|
+
model.from_xml(parse_singular_entity_response(model, response.plain_body))
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
alias :update :create
|
57
|
+
|
58
|
+
def delete(entity)
|
59
|
+
raise NotImplementedError
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete_by_query_string(entity, options = {})
|
63
|
+
url = "#{url_for_resource(model::REST_RESOURCE)}?operation=delete"
|
64
|
+
|
65
|
+
xml = entity.to_xml_ns(options)
|
66
|
+
response = do_http_post(url, valid_xml_document(xml))
|
67
|
+
if response.code.to_i == 200
|
68
|
+
parse_singular_entity_response_for_delete(model, response.plain_body)
|
69
|
+
else
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Service
|
3
|
+
module ServiceCrudJSON
|
4
|
+
|
5
|
+
def fetch_by_id(id, params = {})
|
6
|
+
raise NotImplementedError
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(entity, options = {})
|
10
|
+
raise Quickbooks::InvalidModelException.new(entity.errors.full_messages.join(',')) unless entity.valid?
|
11
|
+
response = do_http(:post, url_for_resource(model.resource_for_singular), entity.to_json, options)
|
12
|
+
if response.code.to_i == 200
|
13
|
+
JSON.parse(response.plain_body)
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
alias :update :create
|
19
|
+
|
20
|
+
def delete
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_by_query_string
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Service
|
3
|
+
class Upload < BaseService
|
4
|
+
|
5
|
+
XML_NODE = "AttachableResponse"
|
6
|
+
|
7
|
+
# path_to_file: String - path to file
|
8
|
+
# mime_type: String - the MIME type of the file, e.g. image/jpeg
|
9
|
+
# attachable: Quickbooks::Model::Attachable meta-data details, can be null
|
10
|
+
def upload(path_to_file, mime_type, attachable = nil)
|
11
|
+
url = url_for_resource("upload")
|
12
|
+
uploadIO = class_for_io.new(path_to_file, mime_type)
|
13
|
+
response = do_http_file_upload(uploadIO, url, attachable)
|
14
|
+
prefix = "AttachableResponse/xmlns:Attachable"
|
15
|
+
if response.code.to_i == 200
|
16
|
+
model.from_xml(parse_singular_entity_response(model, response.plain_body, prefix))
|
17
|
+
else
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def class_for_io
|
23
|
+
oauth.is_a?(OAuth2::AccessToken) ? Faraday::UploadIO : UploadIO
|
24
|
+
end
|
25
|
+
|
26
|
+
def download(uploadId)
|
27
|
+
url = url_for_resource("download/#{uploadId}")
|
28
|
+
do_http_get(url, {}, headers)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def model
|
34
|
+
Quickbooks::Model::Attachable
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Service
|
3
|
+
class Vendor < BaseService
|
4
|
+
|
5
|
+
# override update as sparse is not supported
|
6
|
+
def update(entity, options = {})
|
7
|
+
raise InvalidModelException.new('Vendor sparse update is not supported by Intuit at this time') if options[:sparse] && options[:sparse] == true
|
8
|
+
super(entity, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete(vendor)
|
12
|
+
vendor.active = false
|
13
|
+
update(vendor, :sparse => false)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def model
|
19
|
+
Quickbooks::Model::Vendor
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
attr_accessor :entries
|
5
|
+
|
6
|
+
attr_accessor :body
|
7
|
+
|
8
|
+
# Legacy Attributes (v2)
|
9
|
+
attr_accessor :count, :current_page
|
10
|
+
|
11
|
+
# v3 Attributes
|
12
|
+
attr_accessor :start_position, :max_results, :total_count
|
13
|
+
|
14
|
+
def each(*args, &block)
|
15
|
+
(entries|| []).each *args, &block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Intended to extend the Net::HTTP response object
|
2
|
+
# and adds support for decoding gzip and deflate encoded pages
|
3
|
+
#
|
4
|
+
# Author: Jason Stirk <http://griffin.oobleyboo.com>
|
5
|
+
# Home: http://griffin.oobleyboo.com/projects/http_encoding_helper
|
6
|
+
# Created: 5 September 2007
|
7
|
+
# Last Updated: 23 November 2007
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
#
|
11
|
+
# require 'net/http'
|
12
|
+
# require 'http_encoding_helper'
|
13
|
+
# headers={'Accept-Encoding' => 'gzip, deflate' }
|
14
|
+
# http = Net::HTTP.new('griffin.oobleyboo.com', 80)
|
15
|
+
# http.start do |h|
|
16
|
+
# request = Net::HTTP::Get.new('/', headers)
|
17
|
+
# response = http.request(request)
|
18
|
+
# content=response.plain_body # Method from our library
|
19
|
+
# puts "Transferred: #{response.body.length} bytes"
|
20
|
+
# puts "Compression: #{response['content-encoding']}"
|
21
|
+
# puts "Extracted: #{response.plain_body.length} bytes"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
|
25
|
+
require 'zlib'
|
26
|
+
require 'stringio'
|
27
|
+
|
28
|
+
class Net::HTTPResponse
|
29
|
+
# Return the uncompressed content
|
30
|
+
def plain_body
|
31
|
+
|
32
|
+
encoding = self['Content-Encoding']
|
33
|
+
@_content ||= nil
|
34
|
+
|
35
|
+
return @_content if @_content
|
36
|
+
|
37
|
+
if encoding
|
38
|
+
case encoding
|
39
|
+
when 'gzip'
|
40
|
+
i = Zlib::GzipReader.new(StringIO.new(self.body))
|
41
|
+
@_content = i.read
|
42
|
+
when 'deflate'
|
43
|
+
i = Zlib::Inflate.new
|
44
|
+
@_content = i.inflate(self.body)
|
45
|
+
else
|
46
|
+
raise "Unknown encoding - #{encoding}"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
@_content = self.body
|
50
|
+
end
|
51
|
+
|
52
|
+
@_content
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Util
|
3
|
+
module Logging
|
4
|
+
def log(msg)
|
5
|
+
::Quickbooks.log(msg)
|
6
|
+
end
|
7
|
+
|
8
|
+
def log_xml(str)
|
9
|
+
if ::Quickbooks.log_xml_pretty_print? && !(str and str.empty?)
|
10
|
+
Nokogiri::XML(str).to_xml
|
11
|
+
else
|
12
|
+
str
|
13
|
+
end
|
14
|
+
rescue => e
|
15
|
+
e
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module OauthMultipart
|
2
|
+
end
|
3
|
+
|
4
|
+
require "oauth"
|
5
|
+
|
6
|
+
OAuth::Consumer.class_eval do
|
7
|
+
def create_http_request(http_method, path, *arguments)
|
8
|
+
http_method = http_method.to_sym
|
9
|
+
|
10
|
+
if [:post, :put].include?(http_method)
|
11
|
+
data = arguments.shift
|
12
|
+
end
|
13
|
+
|
14
|
+
# if the base site contains a path, add it now
|
15
|
+
uri = URI.parse(site)
|
16
|
+
path = uri.path + path if uri.path
|
17
|
+
|
18
|
+
headers = arguments.first.is_a?(Hash) ? arguments.shift : {}
|
19
|
+
|
20
|
+
case http_method
|
21
|
+
when :post
|
22
|
+
request = Net::HTTP::Post.new(path,headers)
|
23
|
+
request["Content-Length"] = '0' # Default to 0
|
24
|
+
when :put
|
25
|
+
request = Net::HTTP::Put.new(path,headers)
|
26
|
+
request["Content-Length"] = '0' # Default to 0
|
27
|
+
when :get
|
28
|
+
request = Net::HTTP::Get.new(path,headers)
|
29
|
+
when :delete
|
30
|
+
request = Net::HTTP::Delete.new(path,headers)
|
31
|
+
|
32
|
+
when :head
|
33
|
+
request = Net::HTTP::Head.new(path,headers)
|
34
|
+
when :multipart_post
|
35
|
+
request = Net::HTTP::Post::Multipart.new(path, headers)
|
36
|
+
else
|
37
|
+
raise ArgumentError, "Don't know how to handle http_method: :#{http_method.to_s}"
|
38
|
+
end
|
39
|
+
|
40
|
+
if data.is_a?(Hash)
|
41
|
+
form_data = {}
|
42
|
+
data.each {|k,v| form_data[k.to_s] = v if !v.nil?}
|
43
|
+
request.set_form_data(form_data)
|
44
|
+
elsif data
|
45
|
+
if data.respond_to?(:read)
|
46
|
+
request.body_stream = data
|
47
|
+
if data.respond_to?(:length)
|
48
|
+
request["Content-Length"] = data.length.to_s
|
49
|
+
elsif data.respond_to?(:stat) && data.stat.respond_to?(:size)
|
50
|
+
request["Content-Length"] = data.stat.size.to_s
|
51
|
+
else
|
52
|
+
raise ArgumentError, "Don't know how to send a body_stream that doesn't respond to .length or .stat.size"
|
53
|
+
end
|
54
|
+
else
|
55
|
+
request.body = data.to_s
|
56
|
+
request["Content-Length"] = request.body.length.to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
request
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
OAuth::AccessToken.class_eval do
|
66
|
+
|
67
|
+
def post_with_multipart(*args)
|
68
|
+
multipart_post *args
|
69
|
+
end
|
70
|
+
|
71
|
+
def multipart_post(*args)
|
72
|
+
request(:multipart_post, *args)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
OAuth2::AccessToken.class_eval do
|
77
|
+
|
78
|
+
def post_with_multipart(*args)
|
79
|
+
multipart_post *args
|
80
|
+
end
|
81
|
+
|
82
|
+
def multipart_post(*args)
|
83
|
+
request(:post, *args)
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module NameEntity
|
2
|
+
|
3
|
+
module Quality
|
4
|
+
def email_address=(email_address)
|
5
|
+
self.primary_email_address = Quickbooks::Model::EmailAddress.new(email_address)
|
6
|
+
end
|
7
|
+
|
8
|
+
def email_address
|
9
|
+
primary_email_address
|
10
|
+
end
|
11
|
+
|
12
|
+
def names_cannot_contain_invalid_characters
|
13
|
+
[:name, :display_name, :given_name, :middle_name, :family_name, :print_on_check_name].each do |property|
|
14
|
+
next unless respond_to? property
|
15
|
+
value = send(property).to_s
|
16
|
+
if value.index(':')
|
17
|
+
errors.add(property, ":#{property} cannot contain a colon (:).")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def email_address_is_valid
|
23
|
+
if primary_email_address
|
24
|
+
address = primary_email_address.address.to_s
|
25
|
+
return false if address.length == 0
|
26
|
+
unless address.index('@') && address.index('.')
|
27
|
+
errors.add(:primary_email_address, "Email address must contain @ and . (dot)")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def posting_type_is_valid
|
33
|
+
if posting_type
|
34
|
+
unless %w(Debit Credit).include?(posting_type)
|
35
|
+
errors.add(:posting_type, "Posting Type must be either 'Debit' or 'Credit'")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def billable_status_is_valid
|
41
|
+
if billable_status
|
42
|
+
unless %w(Billable NotBillable HasBeenBilled).include?(billable_status)
|
43
|
+
errors.add(:posting_type, "Posting Type must be either 'Debit' or 'Credit'")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def entity_type_is_valid
|
49
|
+
if entity_type
|
50
|
+
unless %w(Customer Vendor).include?(entity_type)
|
51
|
+
errors.add(:entity_type, "Entity Type must be either 'Customer' or 'Vendor'")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def journal_line_entry_tax
|
57
|
+
if tax_code_ref
|
58
|
+
# tax_applicable_on must be set
|
59
|
+
errors.add(:tax_applicable_on, "TaxApplicableOn must be set when TaxCodeRef is set") if tax_applicable_on.nil?
|
60
|
+
errors.add(:tax_amount, "TaxAmount must be set when TaxCodeRef is set") if tax_amount.nil?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module PermitAlterations
|
66
|
+
|
67
|
+
def valid_for_update?
|
68
|
+
if sync_token.nil?
|
69
|
+
errors.add(:sync_token, "Missing required attribute SyncToken for update")
|
70
|
+
end
|
71
|
+
errors.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
def valid_for_create?
|
75
|
+
valid?
|
76
|
+
errors.empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
# To delete an account Intuit requires we provide Id and SyncToken fields
|
80
|
+
def valid_for_deletion?
|
81
|
+
return false if(id.nil? || sync_token.nil?)
|
82
|
+
id.to_i > 0 && !sync_token.to_s.empty? && sync_token.to_i >= 0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Quickbooks
|
4
|
+
module Util
|
5
|
+
class QueryBuilder
|
6
|
+
|
7
|
+
VALUE_QUOTE = "'"
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
def clause(field, operator, value)
|
13
|
+
value = case value
|
14
|
+
when DateTime, Time
|
15
|
+
value.iso8601
|
16
|
+
when Date
|
17
|
+
value.strftime('%Y-%m-%d')
|
18
|
+
when Array
|
19
|
+
value = value.map{|v| v.to_s.gsub("'", "\\\\'") }
|
20
|
+
else
|
21
|
+
# escape single quotes with an escaped backslash
|
22
|
+
value = value.gsub("'", "\\\\'")
|
23
|
+
end
|
24
|
+
|
25
|
+
if operator.downcase == 'in' && value.is_a?(Array)
|
26
|
+
value = value.map{|v| "#{VALUE_QUOTE}#{v}#{VALUE_QUOTE}"}
|
27
|
+
"#{field} #{operator} (#{value.join(', ')})"
|
28
|
+
else
|
29
|
+
"#{field} #{operator} #{VALUE_QUOTE}#{value}#{VALUE_QUOTE}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|