quickbooks-ruby 0.4.0 → 1.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/lib/quickbooks-ruby.rb +65 -13
  3. data/lib/quickbooks/faraday/middleware/gzip.rb +74 -0
  4. data/lib/quickbooks/model/base_model.rb +13 -2
  5. data/lib/quickbooks/model/batch_request.rb +11 -6
  6. data/lib/quickbooks/model/batch_response.rb +11 -6
  7. data/lib/quickbooks/model/bill.rb +3 -0
  8. data/lib/quickbooks/model/change_data_capture.rb +50 -0
  9. data/lib/quickbooks/model/company_currency.rb +19 -0
  10. data/lib/quickbooks/model/company_info.rb +2 -1
  11. data/lib/quickbooks/model/custom_field.rb +18 -0
  12. data/lib/quickbooks/model/customer.rb +6 -1
  13. data/lib/quickbooks/model/customer_type.rb +15 -0
  14. data/lib/quickbooks/model/deposit_line_detail.rb +2 -2
  15. data/lib/quickbooks/model/description_line_detail.rb +7 -0
  16. data/lib/quickbooks/model/effective_tax_rate.rb +15 -0
  17. data/lib/quickbooks/model/exchange_rate.rb +23 -0
  18. data/lib/quickbooks/model/group_line_detail.rb +2 -1
  19. data/lib/quickbooks/model/invoice.rb +7 -1
  20. data/lib/quickbooks/model/invoice_change.rb +2 -1
  21. data/lib/quickbooks/model/invoice_group_line_detail.rb +14 -0
  22. data/lib/quickbooks/model/invoice_line_item.rb +34 -4
  23. data/lib/quickbooks/model/item.rb +11 -3
  24. data/lib/quickbooks/model/item_group_detail.rb +9 -0
  25. data/lib/quickbooks/model/item_group_line.rb +20 -0
  26. data/lib/quickbooks/model/line.rb +12 -0
  27. data/lib/quickbooks/model/line_ex.rb +9 -0
  28. data/lib/quickbooks/model/linked_transaction.rb +7 -0
  29. data/lib/quickbooks/model/physical_address.rb +2 -2
  30. data/lib/quickbooks/model/preferences.rb +28 -4
  31. data/lib/quickbooks/model/purchase_change.rb +7 -0
  32. data/lib/quickbooks/model/purchase_line_item.rb +1 -0
  33. data/lib/quickbooks/model/purchase_order.rb +3 -1
  34. data/lib/quickbooks/model/refund_receipt_change.rb +8 -0
  35. data/lib/quickbooks/model/report.rb +9 -7
  36. data/lib/quickbooks/model/sales_receipt.rb +4 -2
  37. data/lib/quickbooks/model/tax_rate.rb +1 -1
  38. data/lib/quickbooks/model/time_activity.rb +2 -1
  39. data/lib/quickbooks/model/transfer.rb +21 -0
  40. data/lib/quickbooks/model/vendor.rb +1 -0
  41. data/lib/quickbooks/service/access_token.rb +12 -11
  42. data/lib/quickbooks/service/base_service.rb +148 -24
  43. data/lib/quickbooks/service/batch.rb +1 -1
  44. data/lib/quickbooks/service/change_data_capture.rb +24 -0
  45. data/lib/quickbooks/service/company_currency.rb +18 -0
  46. data/lib/quickbooks/service/credit_memo.rb +6 -0
  47. data/lib/quickbooks/service/custom_field.rb +20 -0
  48. data/lib/quickbooks/service/customer.rb +5 -0
  49. data/lib/quickbooks/service/customer_type.rb +20 -0
  50. data/lib/quickbooks/service/estimate.rb +6 -0
  51. data/lib/quickbooks/service/exchange_rate.rb +25 -0
  52. data/lib/quickbooks/service/invoice.rb +24 -1
  53. data/lib/quickbooks/service/item.rb +5 -0
  54. data/lib/quickbooks/service/payment.rb +13 -0
  55. data/lib/quickbooks/service/preferences.rb +1 -1
  56. data/lib/quickbooks/service/purchase_change.rb +16 -0
  57. data/lib/quickbooks/service/purchase_order.rb +16 -0
  58. data/lib/quickbooks/service/refund_receipt_change.rb +16 -0
  59. data/lib/quickbooks/service/responses/methods.rb +17 -0
  60. data/lib/quickbooks/service/responses/oauth2_http_response.rb +43 -0
  61. data/lib/quickbooks/service/responses/oauth_http_response.rb +17 -0
  62. data/lib/quickbooks/service/sales_receipt.rb +30 -0
  63. data/lib/quickbooks/service/service_crud.rb +21 -0
  64. data/lib/quickbooks/service/service_crud_json.rb +1 -1
  65. data/lib/quickbooks/service/transfer.rb +16 -0
  66. data/lib/quickbooks/service/upload.rb +5 -1
  67. data/lib/quickbooks/util/logging.rb +4 -0
  68. data/lib/quickbooks/util/multipart.rb +2 -65
  69. data/lib/quickbooks/util/name_entity.rb +2 -1
  70. data/lib/quickbooks/util/query_builder.rb +6 -5
  71. data/lib/quickbooks/version.rb +1 -1
  72. metadata +73 -62
@@ -3,7 +3,7 @@ module Quickbooks
3
3
  class Batch < BaseService
4
4
 
5
5
  def make_request(entity, options = {})
6
- response = do_http_post(url_for_resource('batch'), valid_xml_document(entity.to_xml_ns))
6
+ response = do_http_post(url_for_resource('batch'), valid_xml_document(entity.to_xml_ns), options[:query])
7
7
  Quickbooks::Model::BatchResponse.from_xml(response.plain_body)
8
8
  end
9
9
  end
@@ -0,0 +1,24 @@
1
+ module Quickbooks
2
+ module Service
3
+ class ChangeDataCapture < BaseService
4
+
5
+ def url_for_query(entity_list, query=nil)
6
+ q = entity_list.join(",")
7
+ q = "#{q}&#{query}" if query.present?
8
+ return "#{url_for_base}/cdc?entities=#{q}"
9
+ end
10
+
11
+ def since(entity_list, timestamp)
12
+ do_http_get(url_for_query(entity_list, "changedSince=#{URI.encode_www_form_component(timestamp.iso8601)}"))
13
+ model.new(:xml => @last_response_xml)
14
+ end
15
+
16
+ private
17
+
18
+ def model
19
+ Quickbooks::Model::ChangeDataCapture
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Quickbooks
2
+ module Service
3
+ class CompanyCurrency < BaseService
4
+
5
+ def delete(company_currency)
6
+ company_currency.active = false
7
+ update(company_currency, :sparse => true)
8
+ end
9
+
10
+ private
11
+
12
+ def model
13
+ Quickbooks::Model::CompanyCurrency
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -6,6 +6,12 @@ module Quickbooks
6
6
  delete_by_query_string(credit_memo)
7
7
  end
8
8
 
9
+ def pdf(credit_memo)
10
+ url = "#{url_for_resource(model::REST_RESOURCE)}/#{credit_memo.id}/pdf"
11
+ response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
12
+ response.plain_body
13
+ end
14
+
9
15
  private
10
16
 
11
17
  def model
@@ -0,0 +1,20 @@
1
+ module Quickbooks
2
+ module Service
3
+ class CustomField < BaseService
4
+
5
+ def delete(customer_type)
6
+ raise Quickbooks::UnsupportedOperation.new('Deleting CustomerType is not supported by Intuit')
7
+ end
8
+
9
+ def create(customer_type)
10
+ raise Quickbooks::UnsupportedOperation.new('Creating/updating CustomerType is not supported by Intuit')
11
+ end
12
+
13
+ private
14
+
15
+ def model
16
+ Quickbooks::Model::CustomField
17
+ end
18
+ end
19
+ end
20
+ end
@@ -7,6 +7,11 @@ module Quickbooks
7
7
  update(customer, :sparse => true)
8
8
  end
9
9
 
10
+ def fetch_by_id(id, params = {})
11
+ url = "#{url_for_base}/customer/#{id}"
12
+ fetch_object(model, url, params)
13
+ end
14
+
10
15
  private
11
16
 
12
17
  def model
@@ -0,0 +1,20 @@
1
+ module Quickbooks
2
+ module Service
3
+ class CustomerType < BaseService
4
+
5
+ def delete(customer_type)
6
+ raise Quickbooks::UnsupportedOperation.new('Deleting CustomerType is not supported by Intuit')
7
+ end
8
+
9
+ def create(customer_type)
10
+ raise Quickbooks::UnsupportedOperation.new('Creating/updating CustomerType is not supported by Intuit')
11
+ end
12
+
13
+ private
14
+
15
+ def model
16
+ Quickbooks::Model::CustomerType
17
+ end
18
+ end
19
+ end
20
+ end
@@ -5,6 +5,12 @@ module Quickbooks
5
5
  def delete(estimate)
6
6
  delete_by_query_string(estimate)
7
7
  end
8
+
9
+ def pdf(estimate)
10
+ url = "#{url_for_resource(model::REST_RESOURCE)}/#{estimate.id}/pdf"
11
+ response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
12
+ response.plain_body
13
+ end
8
14
 
9
15
  private
10
16
 
@@ -0,0 +1,25 @@
1
+ module Quickbooks
2
+ module Service
3
+ class ExchangeRate < BaseService
4
+
5
+ def fetch_by_currency(source_currency_code, as_of_date = nil)
6
+ url = url_for_resource(model::REST_RESOURCE)
7
+ params = { sourcecurrencycode: source_currency_code }
8
+ params[:asofdate] = as_of_date unless as_of_date.nil?
9
+
10
+ response = do_http_get(url, params)
11
+ if response.code.to_i == 200
12
+ model.from_xml(parse_singular_entity_response(model, response.plain_body))
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def model
21
+ Quickbooks::Model::ExchangeRate
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,10 +6,15 @@ module Quickbooks
6
6
  delete_by_query_string(invoice)
7
7
  end
8
8
 
9
+ def fetch_by_id(id, params = {})
10
+ url = "#{url_for_base}/invoice/#{id}"
11
+ fetch_object(model, url, params)
12
+ end
13
+
9
14
  def send(invoice, email_address=nil)
10
15
  query = email_address.present? ? "?sendTo=#{email_address}" : ""
11
16
  url = "#{url_for_resource(model::REST_RESOURCE)}/#{invoice.id}/send#{query}"
12
- response = do_http_post(url,{})
17
+ response = do_http_post(url, "", {}, { 'Content-Type' => 'application/octet-stream' })
13
18
  if response.code.to_i == 200
14
19
  model.from_xml(parse_singular_entity_response(model, response.plain_body))
15
20
  else
@@ -17,6 +22,24 @@ module Quickbooks
17
22
  end
18
23
  end
19
24
 
25
+ def pdf(invoice)
26
+ url = "#{url_for_resource(model::REST_RESOURCE)}/#{invoice.id}/pdf"
27
+ response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
28
+ response.plain_body
29
+ end
30
+
31
+ def void(invoice, options = {})
32
+ url = "#{url_for_resource(model::REST_RESOURCE)}?operation=void"
33
+
34
+ xml = invoice.to_xml_ns(options)
35
+ response = do_http_post(url, valid_xml_document(xml))
36
+ if response.code.to_i == 200
37
+ model.from_xml(parse_singular_entity_response(model, response.plain_body))
38
+ else
39
+ false
40
+ end
41
+ end
42
+
20
43
  private
21
44
 
22
45
  def model
@@ -7,6 +7,11 @@ module Quickbooks
7
7
  update(item, :sparse => true)
8
8
  end
9
9
 
10
+ def fetch_by_id(id, params = {})
11
+ url = "#{url_for_base}/item/#{id}"
12
+ fetch_object(model, url, params)
13
+ end
14
+
10
15
  private
11
16
 
12
17
  def model
@@ -6,6 +6,19 @@ module Quickbooks
6
6
  delete_by_query_string(payment)
7
7
  end
8
8
 
9
+ def void(entity, options = {})
10
+ raise Quickbooks::InvalidModelException.new(entity.errors.full_messages.join(',')) unless entity.valid?
11
+ xml = entity.to_xml_ns(options)
12
+ url = "#{url_for_resource(model::REST_RESOURCE)}?include=void"
13
+
14
+ response = do_http_post(url, valid_xml_document(xml), {})
15
+ if response.code.to_i == 200
16
+ model.from_xml(parse_singular_entity_response(model, response.plain_body))
17
+ else
18
+ false
19
+ end
20
+ end
21
+
9
22
  private
10
23
 
11
24
  def model
@@ -3,7 +3,7 @@ module Quickbooks
3
3
  class Preferences < BaseService
4
4
 
5
5
  private
6
-
6
+
7
7
  def model
8
8
  Quickbooks::Model::Preferences
9
9
  end
@@ -0,0 +1,16 @@
1
+ module Quickbooks
2
+ module Service
3
+ class PurchaseChange < ChangeService
4
+
5
+ private
6
+
7
+ def entity
8
+ "Purchase"
9
+ end
10
+
11
+ def model
12
+ Quickbooks::Model::PurchaseChange
13
+ end
14
+ end
15
+ end
16
+ end
@@ -6,6 +6,22 @@ module Quickbooks
6
6
  delete_by_query_string(purchase_order)
7
7
  end
8
8
 
9
+ def fetch_by_id(id, params = {})
10
+ url = "#{url_for_base}/purchaseorder/#{id}?minorversion=#{Quickbooks.minorversion}"
11
+ fetch_object(model, url, params)
12
+ end
13
+
14
+ def url_for_query(query = nil, start_position = 1, max_results = 20, options = {})
15
+ url = super(query, start_position, max_results, options)
16
+ "#{url}&minorversion=#{Quickbooks.minorversion}"
17
+ end
18
+
19
+ def pdf(purchase_order)
20
+ url = "#{url_for_resource(model::REST_RESOURCE)}/#{purchase_order.id}/pdf"
21
+ response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
22
+ response.plain_body
23
+ end
24
+
9
25
  private
10
26
 
11
27
  def model
@@ -0,0 +1,16 @@
1
+ module Quickbooks
2
+ module Service
3
+ class RefundReceiptChange < ChangeService
4
+
5
+ private
6
+
7
+ def entity
8
+ "RefundReceipt"
9
+ end
10
+
11
+ def model
12
+ Quickbooks::Model::RefundReceiptChange
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Quickbooks
2
+ module Service
3
+ module Responses
4
+ module Methods
5
+
6
+ def body
7
+ raise "implement me"
8
+ end
9
+
10
+ def code
11
+ raise "implement me"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,43 @@
1
+ module Quickbooks
2
+ module Service
3
+ module Responses
4
+
5
+ class OAuth2HttpResponse
6
+ include Quickbooks::Service::Responses::Methods
7
+
8
+ attr_accessor :real_response
9
+
10
+ # response : Faraday response
11
+ def initialize(response)
12
+ @real_response = response
13
+ end
14
+
15
+ def version
16
+ 2
17
+ end
18
+
19
+ def body
20
+ @real_response.body
21
+ end
22
+
23
+ def plain_body
24
+ body
25
+ end
26
+
27
+ def code
28
+ @real_response.status.to_i
29
+ end
30
+
31
+ def headers
32
+ if @real_response.respond_to?(:headers)
33
+ @real_response.headers
34
+ else
35
+ nil
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
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
+ Quickbooks::Service::Responses::OAuth2HttpResponse.new(response)
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,36 @@ module Quickbooks
6
6
  delete_by_query_string(sales_receipt)
7
7
  end
8
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, "", {}, { 'Content-Type' => 'application/octet-stream' })
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
+
9
39
  private
10
40
 
11
41
  def model
@@ -6,6 +6,15 @@ module Quickbooks
6
6
  fetch_collection(object_query, model, options)
7
7
  end
8
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
+
9
18
  def query_in_batches(object_query=nil, options={})
10
19
  page = 0
11
20
  per_page = options.delete(:per_page) || 1_000
@@ -16,6 +25,18 @@ module Quickbooks
16
25
  end until results.count < per_page
17
26
  end
18
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
+
19
40
  def fetch_by_id(id, params = {})
20
41
  url = "#{url_for_resource(model.resource_for_singular)}/#{id}"
21
42
  fetch_object(model, url, params)