quickbooks-ruby 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/{quickbooks.rb → quickbooks-ruby.rb} +26 -4
  3. data/lib/quickbooks/model/account.rb +91 -0
  4. data/lib/quickbooks/model/account_based_expense_line_detail.rb +15 -0
  5. data/lib/quickbooks/model/base_model.rb +21 -0
  6. data/lib/quickbooks/model/{customer_ref.rb → base_reference.rb} +1 -1
  7. data/lib/quickbooks/model/bill.rb +36 -0
  8. data/lib/quickbooks/model/bill_line_item.rb +23 -0
  9. data/lib/quickbooks/model/bill_payment.rb +34 -0
  10. data/lib/quickbooks/model/bill_payment_check.rb +12 -0
  11. data/lib/quickbooks/model/bill_payment_credit_card.rb +10 -0
  12. data/lib/quickbooks/model/bill_payment_line_item.rb +21 -0
  13. data/lib/quickbooks/model/check_payment.rb +11 -0
  14. data/lib/quickbooks/model/credit_card_payment.rb +17 -0
  15. data/lib/quickbooks/model/credit_memo.rb +38 -0
  16. data/lib/quickbooks/model/customer.rb +18 -15
  17. data/lib/quickbooks/model/discount_override.rb +5 -3
  18. data/lib/quickbooks/model/invoice.rb +41 -19
  19. data/lib/quickbooks/model/invoice_line_item.rb +6 -6
  20. data/lib/quickbooks/model/item.rb +24 -17
  21. data/lib/quickbooks/model/line.rb +28 -0
  22. data/lib/quickbooks/model/payment_line_detail.rb +6 -4
  23. data/lib/quickbooks/model/payment_method.rb +14 -0
  24. data/lib/quickbooks/model/physical_address.rb +18 -2
  25. data/lib/quickbooks/model/sales_item_line_detail.rb +9 -7
  26. data/lib/quickbooks/model/sales_receipt.rb +44 -0
  27. data/lib/quickbooks/model/sub_total_line_detail.rb +7 -5
  28. data/lib/quickbooks/service/account.rb +22 -0
  29. data/lib/quickbooks/service/base_service.rb +45 -60
  30. data/lib/quickbooks/service/bill.rb +15 -0
  31. data/lib/quickbooks/service/bill_payment.rb +15 -0
  32. data/lib/quickbooks/service/credit_memo.rb +15 -0
  33. data/lib/quickbooks/service/payment_method.rb +23 -0
  34. data/lib/quickbooks/service/sales_receipt.rb +15 -0
  35. data/lib/quickbooks/service/service_crud.rb +4 -8
  36. data/lib/quickbooks/util/class_util.rb +14 -0
  37. data/lib/quickbooks/{http_encoding_helper.rb → util/http_encoding_helper.rb} +16 -11
  38. data/lib/quickbooks/version.rb +1 -1
  39. metadata +26 -6
  40. data/lib/quickbooks/model/invoice_item_ref.rb +0 -21
@@ -1,10 +1,12 @@
1
1
  module Quickbooks
2
2
  module Model
3
3
  class DiscountOverride < BaseModel
4
- xml_accessor :discount_ref, :from => 'DiscountRef', :as => Integer
4
+ xml_accessor :discount_ref, :from => 'DiscountRef', :as => BaseReference
5
5
  xml_accessor :percent_based, :from => 'PercentBased'
6
- xml_accessor :discount_percent, :from => 'DiscountPercent', :as => Float
7
- xml_accessor :discount_account_ref, :from => 'DiscountAccountRef', :as => Integer
6
+ xml_accessor :discount_percent, :from => 'DiscountPercent', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7
+ xml_accessor :discount_account_ref, :from => 'DiscountAccountRef', :as => BaseReference
8
+
9
+ reference_setters :discount_ref, :discount_account_ref
8
10
 
9
11
  def percent_based?
10
12
  percent_based.to_s == 'true'
@@ -13,49 +13,75 @@ module Quickbooks
13
13
  REST_RESOURCE = 'invoice'
14
14
  XML_COLLECTION_NODE = "Invoice"
15
15
  XML_NODE = "Invoice"
16
+ EMAIL_STATUS_NEED_TO_SEND = 'NeedToSend'
16
17
 
17
18
  xml_accessor :id, :from => 'Id', :as => Integer
18
19
  xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
19
- xml_accessor :meta_data, :from => 'MetaData', :as => Quickbooks::Model::MetaData
20
- xml_accessor :custom_fields, :from => 'CustomField', :as => [Quickbooks::Model::CustomField]
20
+ xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
21
+ xml_accessor :custom_fields, :from => 'CustomField', :as => [CustomField]
21
22
  xml_accessor :doc_number, :from => 'DocNumber'
22
23
  xml_accessor :txn_date, :from => 'TxnDate', :as => Date
23
24
  xml_accessor :private_note, :from => 'PrivateNote'
24
- xml_accessor :linked_transactions, :from => 'LinkedTxn', :as => [Quickbooks::Model::LinkedTransaction]
25
- xml_accessor :line_items, :from => 'Line', :as => [Quickbooks::Model::InvoiceLineItem]
25
+ xml_accessor :linked_transactions, :from => 'LinkedTxn', :as => [LinkedTransaction]
26
+ xml_accessor :line_items, :from => 'Line', :as => [InvoiceLineItem]
26
27
  xml_accessor :txn_tax_detail, :from => 'TxnTaxDetail'
27
- xml_accessor :customer_ref, :from => 'CustomerRef', :as => Quickbooks::Model::CustomerRef
28
+ xml_accessor :customer_ref, :from => 'CustomerRef', :as => BaseReference
28
29
  xml_accessor :customer_memo, :from => 'CustomerMemo'
29
- xml_accessor :billing_address, :from => 'BillAddr', :as => Quickbooks::Model::PhysicalAddress
30
- xml_accessor :shipping_address, :from => 'ShipAddr', :as => Quickbooks::Model::PhysicalAddress
31
- xml_accessor :class_ref, :from => 'ClassRef'
32
- xml_accessor :sales_term_ref, :from => 'SalesTermRef', :as => Integer
30
+ xml_accessor :billing_address, :from => 'BillAddr', :as => PhysicalAddress
31
+ xml_accessor :shipping_address, :from => 'ShipAddr', :as => PhysicalAddress
32
+ xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
33
+ xml_accessor :sales_term_ref, :from => 'SalesTermRef', :as => BaseReference
33
34
  xml_accessor :due_date, :from => 'DueDate', :as => Date
34
- xml_accessor :ship_method_ref, :from => 'ShipMethodRef'
35
+ xml_accessor :ship_method_ref, :from => 'ShipMethodRef', :as => BaseReference
35
36
  xml_accessor :ship_date, :from => 'ShipDate', :as => Date
36
37
  xml_accessor :tracking_num, :from => 'TrackingNum'
37
- xml_accessor :ar_account_ref, :from => 'ARAccountRef', :as => Integer
38
- xml_accessor :total_amount, :from => 'TotalAmt', :as => Float
38
+ xml_accessor :ar_account_ref, :from => 'ARAccountRef', :as => BaseReference
39
+ xml_accessor :total_amount, :from => 'TotalAmt', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
39
40
  xml_accessor :apply_tax_after_discount, :from => 'ApplyTaxAfterDiscount'
40
41
  xml_accessor :print_status, :from => 'PrintStatus'
41
42
  xml_accessor :email_status, :from => 'EmailStatus'
42
- xml_accessor :balance, :from => 'Balance', :as => Float
43
- xml_accessor :deposit, :from => 'Deposit', :as => Float
44
- xml_accessor :department_ref, :from => 'DepartmentRef'
43
+ xml_accessor :balance, :from => 'Balance', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
44
+ xml_accessor :deposit, :from => 'Deposit', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
45
+ xml_accessor :department_ref, :from => 'DepartmentRef', :as => BaseReference
45
46
  xml_accessor :allow_ipn_payment, :from => 'AllowIPNPayment'
47
+ xml_accessor :bill_email, :from => 'BillEmail', :as => EmailAddress
46
48
  xml_accessor :allow_online_payment, :from => 'AllowOnlinePayment'
47
49
  xml_accessor :allow_online_credit_card_payment, :from => 'AllowOnlineCreditCardPayment'
48
50
  xml_accessor :allow_online_ach_payment, :from => 'AllowOnlineACHPayment'
49
51
 
52
+ reference_setters :customer_ref, :class_ref, :sales_term_ref, :ship_method_ref
53
+ reference_setters :ar_account_ref, :department_ref
54
+
50
55
  #== Validations
51
56
  validates_length_of :line_items, :minimum => 1
52
57
  validate :existence_of_customer_ref
58
+ validate :required_bill_email_if_email_delivery
53
59
 
54
60
  def initialize
55
61
  ensure_line_items_initialization
56
62
  super
57
63
  end
58
64
 
65
+ def required_bill_email_if_email_delivery
66
+ return unless email_status_for_delivery?
67
+
68
+ if bill_email.nil?
69
+ errors.add(:bill_email, "BillEmail is required if EmailStatus=NeedToSend")
70
+ end
71
+ end
72
+
73
+ def billing_email_address=(email_address_string)
74
+ self.bill_email = EmailAddress.new(email_address_string)
75
+ end
76
+
77
+ def wants_billing_email_sent!
78
+ self.email_status = EMAIL_STATUS_NEED_TO_SEND
79
+ end
80
+
81
+ def email_status_for_delivery?
82
+ email_status == EMAIL_STATUS_NEED_TO_SEND
83
+ end
84
+
59
85
  def apply_tax_after_discount?
60
86
  apply_tax_after_discount.to_s == 'true'
61
87
  end
@@ -76,10 +102,6 @@ module Quickbooks
76
102
  allow_online_ach_payment.to_s == 'true'
77
103
  end
78
104
 
79
- def customer_id=(customer_id)
80
- self.customer_ref = Quickbooks::Model::CustomerRef.new(customer_id)
81
- end
82
-
83
105
  private
84
106
 
85
107
  def existence_of_customer_ref
@@ -10,13 +10,13 @@ module Quickbooks
10
10
  xml_accessor :id, :from => 'Id', :as => Integer
11
11
  xml_accessor :line_num, :from => 'LineNum', :as => Integer
12
12
  xml_accessor :description, :from => 'Description'
13
- xml_accessor :amount, :from => 'Amount', :as => Float
13
+ xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
14
14
  xml_accessor :detail_type, :from => 'DetailType'
15
15
 
16
16
  #== Various detail types
17
- xml_accessor :sales_line_item_detail, :from => 'SalesItemLineDetail', :as => Quickbooks::Model::SalesItemLineDetail
18
- xml_accessor :sub_total_line_detail, :from => 'SubTotalLineDetail', :as => Quickbooks::Model::SubTotalLineDetail
19
- xml_accessor :payment_line_detail, :from => 'PaymentLineDetail', :as => Quickbooks::Model::PaymentLineDetail
17
+ xml_accessor :sales_line_item_detail, :from => 'SalesItemLineDetail', :as => SalesItemLineDetail
18
+ xml_accessor :sub_total_line_detail, :from => 'SubTotalLineDetail', :as => SubTotalLineDetail
19
+ xml_accessor :payment_line_detail, :from => 'PaymentLineDetail', :as => PaymentLineDetail
20
20
 
21
21
  def sales_item?
22
22
  detail_type.to_s == SALES_LINE_ITEM_DETAIL
@@ -28,14 +28,14 @@ module Quickbooks
28
28
 
29
29
  def sales_item!
30
30
  self.detail_type = SALES_LINE_ITEM_DETAIL
31
- self.sales_line_item_detail = Quickbooks::Model::SalesItemLineDetail.new
31
+ self.sales_line_item_detail = SalesItemLineDetail.new
32
32
 
33
33
  yield self.sales_line_item_detail if block_given?
34
34
  end
35
35
 
36
36
  def payment_item!
37
37
  self.detail_type = PAYMENT_LINE_DETAIL
38
- self.payment_line_detail = Quickbooks::Model::PaymentLineDetail.new
38
+ self.payment_line_detail = PaymentLineDetail.new
39
39
 
40
40
  yield self.payment_line_detail if block_given?
41
41
  end
@@ -19,31 +19,38 @@ module Quickbooks
19
19
  xml_name 'Item'
20
20
  xml_accessor :id, :from => 'Id', :as => Integer
21
21
  xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
22
- xml_accessor :meta_data, :from => 'MetaData', :as => Quickbooks::Model::MetaData
23
- xml_accessor :attachable_ref, :from => 'AttachableRef', :as => Integer
22
+ xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
24
23
  xml_accessor :name, :from => 'Name'
25
24
  xml_accessor :description, :from => 'Description'
26
25
  xml_accessor :active, :from => 'Active'
27
- xml_accessor :parent_ref, :from => 'ParentRef', :as => Integer
28
26
  xml_accessor :sub_item, :from => 'SubItem'
29
- xml_accessor :unit_price, :from => 'UnitPrice', :as => Float
30
- xml_accessor :rate_percent, :from => 'RatePercent', :as => Float
31
- xml_accessor :type, :from => 'Type'
32
- xml_accessor :taxable, :from => 'Taxable'
33
- xml_accessor :asset_account_ref, :from => 'AssetAccountRef', :as => Integer
34
- xml_accessor :income_account_ref, :from => 'IncomeAccountRef', :as => Integer
35
- xml_accessor :purchase_desc, :from => 'PurchaseDesc'
36
- xml_accessor :purchase_cost, :from => 'PurchaseCost', :as => Float
37
- xml_accessor :expense_account_ref, :from => 'ExpenseAccountRef', :as => Integer
38
- xml_accessor :quantity_on_hand, :from => 'QtyOnHand', :as => Float
39
- xml_accessor :sales_tax_code_ref, :from => 'SalesTaxCodeRef', :as => Integer
40
- xml_accessor :purchase_tax_code_ref, :from => 'PurchaseTaxCodeRef', :as => Integer
41
- xml_accessor :track_quantity_on_hand, :from => 'TrackQtyOnHand'
42
- xml_accessor :asset_account, :from => 'AssetAccount', :as => Integer
27
+ xml_accessor :parent_ref, :from => 'ParentRef', :as => Integer
43
28
  xml_accessor :level, :from => 'Level', :as => Integer
29
+
30
+ # read-only
31
+ xml_accessor :fully_qualified_name, :from => 'FullyQualifiedName'
32
+
33
+ xml_accessor :taxable, :from => 'Taxable'
44
34
  xml_accessor :sales_tax_included, :from => 'SalesTaxIncluded'
35
+ xml_accessor :unit_price, :from => 'UnitPrice', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
36
+ xml_accessor :rate_percent, :from => 'RatePercent', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
37
+ xml_accessor :type, :from => 'Type'
38
+ xml_accessor :income_account_ref, :from => 'IncomeAccountRef', :as => BaseReference
39
+ xml_accessor :purchase_desc, :from => 'PurchaseDesc'
45
40
  xml_accessor :purchase_tax_included, :from => 'PurchaseTaxIncluded'
41
+ xml_accessor :purchase_cost, :from => 'PurchaseCost', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
42
+ xml_accessor :expense_account_ref, :from => 'ExpenseAccountRef', :as => BaseReference
43
+ xml_accessor :asset_account_ref, :from => 'AssetAccountRef', :as => BaseReference
44
+ xml_accessor :track_quantity_on_hand, :from => 'TrackQtyOnHand'
45
+ xml_accessor :quantity_on_hand, :from => 'QtyOnHand', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
46
+ xml_accessor :sales_tax_code_ref, :from => 'SalesTaxCodeRef', :as => BaseReference
47
+ xml_accessor :purchase_tax_code_ref, :from => 'PurchaseTaxCodeRef', :as => BaseReference
48
+ xml_accessor :inv_start_date, :from => 'InvStartDate', :as => Date
49
+
50
+ reference_setters :parent_ref, :income_account_ref, :expense_account_ref
51
+ reference_setters :asset_account_ref, :sales_tax_code_ref, :purchase_tax_code_ref
46
52
 
53
+ #== Validations
47
54
  validates_length_of :name, :minimum => 1
48
55
  validates_inclusion_of :type, :in => ITEM_TYPES
49
56
 
@@ -0,0 +1,28 @@
1
+ module Quickbooks
2
+ module Model
3
+ class Line < BaseModel
4
+ #== Constants
5
+ SALES_LINE_ITEM_DETAIL = 'SalesItemLineDetail'
6
+ SUB_TOTAL_LINE_DETAIL = 'SubTotalLineDetail'
7
+ PAYMENT_LINE_DETAIL = 'PaymentLineDetail'
8
+
9
+ xml_accessor :id, :from => 'Id', :as => Integer
10
+ xml_accessor :line_num, :from => 'LineNum', :as => Integer
11
+ xml_accessor :description, :from => 'Description'
12
+ xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
13
+ xml_accessor :detail_type, :from => 'DetailType'
14
+
15
+ #== Various detail types
16
+ xml_accessor :sales_item_line_detail, :from => 'SalesItemLineDetail', :as => SalesItemLineDetail
17
+ xml_accessor :sub_total_line_detail, :from => 'SubTotalLineDetail', :as => SubTotalLineDetail
18
+ xml_accessor :payment_line_detail, :from => 'PaymentLineDetail', :as => PaymentLineDetail
19
+
20
+ def sales_item!
21
+ self.detail_type = SALES_LINE_ITEM_DETAIL
22
+ self.sales_item_line_detail = SalesItemLineDetail.new
23
+
24
+ yield self.sales_item_line_detail if block_given?
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,10 +1,12 @@
1
1
  module Quickbooks
2
2
  module Model
3
3
  class PaymentLineDetail < BaseModel
4
- xml_accessor :item_ref, :from => 'ItemRef', :as => Integer
5
- xml_accessor :class_ref, :from => 'ClassRef', :as => Integer
6
- xml_accessor :balance, :from => 'Balance', :as => Float
7
- xml_accessor :discount, :from => 'Discount', :as => Quickbooks::Model::DiscountOverride
4
+ xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5
+ xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6
+ xml_accessor :balance, :from => 'Balance', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7
+ xml_accessor :discount, :from => 'Discount', :as => DiscountOverride
8
+
9
+ reference_setters :item_ref, :class_ref
8
10
  end
9
11
  end
10
12
  end
@@ -0,0 +1,14 @@
1
+ module Quickbooks
2
+ module Model
3
+ class PaymentMethod < BaseModel
4
+ REST_RESOURCE = 'payment_method'
5
+ XML_COLLECTION_NODE = "PaymentMethod"
6
+ XML_NODE = "PaymentMethod"
7
+
8
+ xml_accessor :id, :from => 'Id', :as => Integer
9
+ xml_accessor :name, :from => 'Name'
10
+ xml_accessor :active, :from => 'Active'
11
+ xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
12
+ end
13
+ end
14
+ end
@@ -12,13 +12,29 @@ module Quickbooks
12
12
  xml_accessor :country_sub_division_code, :from => 'CountrySubDivisionCode'
13
13
  xml_accessor :postal_code, :from => 'PostalCode'
14
14
  xml_accessor :note, :from => 'Note'
15
- xml_accessor :lat, :from => 'Lat', :as => Float
16
- xml_accessor :lon, :from => 'Long', :as => Float
15
+ xml_accessor :lat, :from => 'Lat'
16
+ xml_accessor :lon, :from => 'Long'
17
17
 
18
18
  def zip
19
19
  postal_code
20
20
  end
21
21
 
22
+ def lat_to_f
23
+ BigDecimal.new(lat)
24
+ end
25
+
26
+ def lon_to_f
27
+ BigDecimal.new(lon)
28
+ end
29
+
30
+ def have_lat?
31
+ lat.to_s != "INVALID"
32
+ end
33
+
34
+ def have_lon?
35
+ lon.to_s != "INVALID"
36
+ end
37
+
22
38
  end
23
39
  end
24
40
  end
@@ -1,14 +1,16 @@
1
1
  module Quickbooks
2
2
  module Model
3
3
  class SalesItemLineDetail < BaseModel
4
- xml_accessor :item_ref, :from => 'ItemRef', :as => Integer
5
- xml_accessor :class_ref, :from => 'ClassRef', :as => Integer
6
- xml_accessor :unit_price, :from => 'UnitPrice', :as => Float
7
- xml_accessor :rate_percent, :from => 'RatePercent', :as => Float
8
- xml_accessor :price_level_ref, :from => 'PriceLevelRef', :as => Integer
9
- xml_accessor :quantity, :from => 'Qty', :as => Float
10
- xml_accessor :tax_code_ref, :from => 'TaxCodeRef'
4
+ xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5
+ xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6
+ xml_accessor :unit_price, :from => 'UnitPrice', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7
+ xml_accessor :rate_percent, :from => 'RatePercent', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
8
+ xml_accessor :price_level_ref, :from => 'PriceLevelRef', :as => BaseReference
9
+ xml_accessor :quantity, :from => 'Qty', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
10
+ xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
11
11
  xml_accessor :service_date, :from => 'ServiceDate', :as => Date
12
+
13
+ reference_setters :item_ref, :class_ref, :price_level_ref, :tax_code_ref
12
14
  end
13
15
  end
14
16
  end
@@ -0,0 +1,44 @@
1
+ module Quickbooks
2
+ module Model
3
+ class SalesReceipt < BaseModel
4
+ XML_COLLECTION_NODE = "SalesReceipt"
5
+ XML_NODE = "SalesReceipt"
6
+ REST_RESOURCE = 'salesreceipt'
7
+
8
+ xml_accessor :id, :from => 'Id', :as => Integer
9
+ xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
10
+ xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
11
+ xml_accessor :doc_number, :from => 'DocNumber'
12
+ xml_accessor :placed_on, :from => 'TxnDate', :as => Time
13
+
14
+ xml_accessor :line_items, :from => 'Line', :as => [Line]
15
+ xml_accessor :customer_ref, :from => 'CustomerRef', :as => BaseReference
16
+ xml_accessor :bill_email, :from => 'BillEmail', :as => EmailAddress
17
+ xml_accessor :bill_address, :from => 'BillAddr', :as => PhysicalAddress
18
+ xml_accessor :ship_address, :from => 'ShipAddr', :as => PhysicalAddress
19
+
20
+ xml_accessor :po_number, :from => 'PONumber'
21
+
22
+ xml_accessor :ship_method_ref, :from => 'ShipMethodRef', :as => BaseReference
23
+ xml_accessor :ship_date, :from => 'ShipDate', :as => Time
24
+ xml_accessor :tracking_num, :from => 'TrackingNum'
25
+
26
+ xml_accessor :payment_method_ref, :from => 'PaymentMethodRef', :as => BaseReference
27
+ xml_accessor :payment_ref_number, :from => 'PaymentRefNum'
28
+
29
+ xml_accessor :deposit_to_account_ref, :from => 'DepositToAccountRef', :as => BaseReference
30
+
31
+ # readonly
32
+ xml_accessor :total, :from => 'TotalAmt', :as => BigDecimal
33
+
34
+ reference_setters :customer_ref, :ship_method_ref, :payment_method_ref, :deposit_to_account_ref
35
+
36
+ validates_length_of :line_items, :minimum => 1
37
+
38
+ def email=(email)
39
+ self.bill_email = EmailAddress.new(email)
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -1,11 +1,13 @@
1
1
  module Quickbooks
2
2
  module Model
3
3
  class SubTotalLineDetail < BaseModel
4
- xml_accessor :item_ref, :from => 'ItemRef', :as => Integer
5
- xml_accessor :class_ref, :from => 'ClassRef'
6
- xml_accessor :unit_price, :from => 'UnitPrice', :as => Float
7
- xml_accessor :quantity, :from => 'Qty', :as => Float
8
- xml_accessor :tax_code_ref, :from => 'TaxCodeRef'
4
+ xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5
+ xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6
+ xml_accessor :unit_price, :from => 'UnitPrice', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7
+ xml_accessor :quantity, :from => 'Qty', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
8
+ xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
9
+
10
+ reference_setters :item_ref, :class_ref, :tax_code_ref
9
11
  end
10
12
  end
11
13
  end
@@ -0,0 +1,22 @@
1
+ module Quickbooks
2
+ module Service
3
+ class Account < BaseService
4
+ include ServiceCrud
5
+
6
+ def delete(account)
7
+ account.active = false
8
+ update(account, :sparse => true)
9
+ end
10
+
11
+ private
12
+
13
+ def default_model_query
14
+ "SELECT * FROM ACCOUNT"
15
+ end
16
+
17
+ def model
18
+ Quickbooks::Model::Account
19
+ end
20
+ end
21
+ end
22
+ end
@@ -2,14 +2,19 @@
2
2
  require 'uri'
3
3
  require 'cgi'
4
4
 
5
- class IntuitRequestException < StandardError
6
- attr_accessor :message, :code, :detail, :type
7
- def initialize(msg)
8
- self.message = msg
9
- super(msg)
5
+ unless Quickbooks::Util::ClassUtil.defined?("InvalidModelException")
6
+ class IntuitRequestException < StandardError
7
+ attr_accessor :message, :code, :detail, :type
8
+ def initialize(msg)
9
+ self.message = msg
10
+ super(msg)
11
+ end
10
12
  end
11
13
  end
12
- class AuthorizationFailure < StandardError; end
14
+
15
+ unless Quickbooks::Util::ClassUtil.defined?("InvalidModelException")
16
+ class AuthorizationFailure < StandardError; end
17
+ end
13
18
 
14
19
  module Quickbooks
15
20
  module Service
@@ -25,6 +30,7 @@ module Quickbooks
25
30
  XML_NS = %{xmlns="http://schema.intuit.com/finance/v3"}
26
31
  HTTP_CONTENT_TYPE = 'application/xml'
27
32
  HTTP_ACCEPT = 'application/xml'
33
+ HTTP_ACCEPT_ENCODING = 'gzip, deflate'
28
34
 
29
35
  def initialize()
30
36
  @base_uri = 'https://qb.sbfinance.intuit.com/v3/company'
@@ -51,19 +57,17 @@ module Quickbooks
51
57
  "#{@base_uri}/#{@company_id}"
52
58
  end
53
59
 
54
- def url_for_query(query = "")
55
- "#{url_for_base}/query?query=#{URI.encode(query)}"
60
+ def url_for_query(query = nil, start_position = 1, max_results = 20)
61
+ query ||= default_model_query
62
+ query = "#{query} STARTPOSITION #{start_position} MAXRESULTS #{max_results}"
63
+
64
+ "#{url_for_base}/query?query=#{URI.encode_www_form_component(query)}"
56
65
  end
57
66
 
58
67
  private
59
68
 
60
69
  def parse_xml(xml)
61
- @last_response_xml =
62
- begin
63
- x = Nokogiri::XML(xml)
64
- #x.document.remove_namespaces!
65
- x
66
- end
70
+ @last_response_xml = Nokogiri::XML(xml)
67
71
  end
68
72
 
69
73
  def valid_xml_document(xml)
@@ -94,43 +98,11 @@ module Quickbooks
94
98
  end
95
99
 
96
100
  max_results = (page * per_page)
97
-
98
- query = "#{query} STARTPOSITION #{start_position} MAXRESULTS #{max_results}"
99
- response = do_http_get(url_for_query(query))
101
+ response = do_http_get(url_for_query(query, start_position, max_results))
100
102
 
101
103
  parse_collection(response, model)
102
104
  end
103
105
 
104
- #
105
- # def fetch_collection2(model, custom_field_query = nil, filters = [], page = 1, per_page = 20, sort = nil, options ={})
106
- # raise ArgumentError, "missing model to instantiate" if model.nil?
107
- #
108
- # post_body_tags = []
109
- #
110
- # # pagination parameters must come first
111
- # post_body_tags << "<StartPage>#{page}</StartPage>"
112
- # post_body_tags << "<ChunkSize>#{per_page}</ChunkSize>"
113
- #
114
- # # ... followed by any filters
115
- # if filters.is_a?(Array) && filters.length > 0
116
- # filters = enforce_filter_order(filters).compact
117
- # post_body_tags << filters.collect { |f| f.to_xml }
118
- # post_body_tags.flatten!
119
- # end
120
- #
121
- # if sort
122
- # post_body_tags << sort.to_xml
123
- # end
124
- #
125
- # post_body_tags << custom_field_query
126
- #
127
- # xml_query_tag = "#{model::XML_NODE}Query"
128
- # body = %Q{<?xml version="1.0" encoding="utf-8"?>\n<#{xml_query_tag} xmlns="http://www.intuit.com/sb/cdm/v2">#{post_body_tags.join}</#{xml_query_tag}>}
129
- #
130
- # response = do_http_post(url_for_resource(model::REST_RESOURCE), body, {}, {'Content-Type' => 'text/xml'})
131
- # parse_collection(response, model)
132
- # end
133
-
134
106
  def parse_collection(response, model)
135
107
  if response
136
108
  collection = Quickbooks::Collection.new
@@ -205,13 +177,14 @@ module Quickbooks
205
177
  unless headers.has_key?('Content-Type')
206
178
  headers['Content-Type'] = 'text/xml'
207
179
  end
180
+
208
181
  response = do_http_post(url, body.strip, params, headers)
209
182
 
210
183
  result = nil
211
184
  if response
212
185
  case response.code.to_i
213
186
  when 200
214
- result = Quickbooks::Model::RestResponse.from_xml(response.body)
187
+ result = Quickbooks::Model::RestResponse.from_xml(response.plain_body)
215
188
  when 401
216
189
  raise IntuitRequestException.new("Authorization failure: token timed out?")
217
190
  when 404
@@ -235,14 +208,28 @@ module Quickbooks
235
208
  raise "OAuth client has not been initialized. Initialize with setter access_token="
236
209
  end
237
210
  unless headers.has_key?('Content-Type')
238
- headers.merge!({'Content-Type' => HTTP_CONTENT_TYPE})
211
+ headers['Content-Type'] = HTTP_CONTENT_TYPE
212
+ end
213
+ unless headers.has_key?('Accept')
214
+ headers['Accept'] = HTTP_ACCEPT
215
+ end
216
+ unless headers.has_key?('Accept-Encoding')
217
+ headers['Accept-Encoding'] = HTTP_ACCEPT_ENCODING
239
218
  end
240
- # log "------ New Request ------"
241
- # log "METHOD = #{method}"
242
- # log "RESOURCE = #{url}"
243
- # log "BODY(#{body.class}) = #{body == nil ? "<NIL>" : body.inspect}"
244
- # log "HEADERS = #{headers.inspect}"
245
- response = @oauth.request(method, url, body, headers)
219
+
220
+ #log "METHOD = #{method}"
221
+ #log "RESOURCE = #{url}"
222
+ #log "BODY(#{body.class}) = #{body == nil ? "<NIL>" : body.inspect}"
223
+ #log "HEADERS = #{headers.inspect}"
224
+
225
+ response = case method
226
+ when :get
227
+ @oauth.get(url, headers)
228
+ when :post
229
+ @oauth.post(url, body, headers)
230
+ else
231
+ raise "Dont know how to perform that HTTP operation"
232
+ end
246
233
  check_response(response)
247
234
  end
248
235
 
@@ -255,9 +242,7 @@ module Quickbooks
255
242
  end
256
243
 
257
244
  def check_response(response)
258
- # puts "RESPONSE CODE = #{response.code}"
259
- # puts "RESPONSE BODY = #{response.body}"
260
- parse_xml(response.body)
245
+ parse_xml(response.plain_body)
261
246
  status = response.code.to_i
262
247
  case status
263
248
  when 200
@@ -274,13 +259,13 @@ module Quickbooks
274
259
  when 400, 500
275
260
  parse_and_raise_exception
276
261
  else
277
- raise "HTTP Error Code: #{status}, Msg: #{response.body}"
262
+ raise "HTTP Error Code: #{status}, Msg: #{response.plain_body}"
278
263
  end
279
264
  end
280
265
 
281
266
  def parse_and_raise_exception
282
267
  err = parse_intuit_error
283
- ex = IntuitRequestException.new(err[:message])
268
+ ex = IntuitRequestException.new("#{err[:message]}:\n\t#{err[:detail]}")
284
269
  ex.code = err[:code]
285
270
  ex.detail = err[:detail]
286
271
  ex.type = err[:type]