quickbooks 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/Rakefile +4 -2
- data/doc/classes/Array.html +333 -40
- data/doc/classes/Array.src/M000037.html +18 -0
- data/doc/classes/Array.src/M000038.html +21 -0
- data/doc/classes/Array.src/M000039.html +18 -0
- data/doc/classes/Array.src/M000040.html +19 -0
- data/doc/classes/Array.src/M000041.html +18 -0
- data/doc/classes/Array.src/{M000004.html → M000042.html} +1 -1
- data/doc/classes/Array.src/M000043.html +18 -0
- data/doc/classes/Array.src/M000044.html +18 -0
- data/doc/classes/Array.src/{M000001.html → M000045.html} +1 -1
- data/doc/classes/Array.src/{M000002.html → M000046.html} +1 -1
- data/doc/classes/Array.src/{M000003.html → M000047.html} +1 -1
- data/doc/classes/Array.src/M000048.html +23 -0
- data/doc/classes/Array.src/{M000005.html → M000049.html} +1 -1
- data/doc/classes/Array.src/{M000006.html → M000050.html} +2 -2
- data/doc/classes/Array.src/{M000007.html → M000051.html} +1 -1
- data/doc/classes/Array.src/{M000008.html → M000052.html} +1 -1
- data/doc/classes/Array.src/M000053.html +18 -0
- data/doc/classes/Array.src/M000054.html +20 -0
- data/doc/classes/Array.src/M000055.html +18 -0
- data/doc/classes/Array.src/M000056.html +34 -0
- data/doc/classes/Array.src/M000057.html +19 -0
- data/doc/classes/Array.src/M000058.html +29 -0
- data/doc/classes/Array.src/M000059.html +18 -0
- data/doc/classes/Array.src/M000060.html +20 -0
- data/doc/classes/Array.src/M000061.html +18 -0
- data/doc/classes/Array.src/M000062.html +18 -0
- data/doc/classes/Array.src/M000063.html +19 -0
- data/doc/classes/Class.html +25 -6
- data/doc/classes/Class.src/M000075.html +18 -0
- data/doc/classes/Class.src/M000076.html +18 -0
- data/doc/classes/Hash.html +329 -103
- data/doc/classes/Hash.src/M000004.html +18 -0
- data/doc/classes/Hash.src/M000005.html +21 -0
- data/doc/classes/Hash.src/M000006.html +18 -0
- data/doc/classes/Hash.src/M000007.html +21 -0
- data/doc/classes/Hash.src/M000008.html +18 -0
- data/doc/classes/Hash.src/M000009.html +6 -4
- data/doc/classes/Hash.src/M000010.html +4 -7
- data/doc/classes/Hash.src/M000011.html +8 -4
- data/doc/classes/Hash.src/M000012.html +4 -7
- data/doc/classes/Hash.src/M000013.html +7 -4
- data/doc/classes/Hash.src/M000014.html +4 -7
- data/doc/classes/Hash.src/M000015.html +6 -12
- data/doc/classes/Hash.src/M000016.html +4 -6
- data/doc/classes/Hash.src/M000017.html +7 -4
- data/doc/classes/Hash.src/M000018.html +4 -6
- data/doc/classes/Hash.src/M000019.html +5 -22
- data/doc/classes/Hash.src/M000020.html +14 -5
- data/doc/classes/Hash.src/M000021.html +7 -5
- data/doc/classes/Hash.src/M000022.html +5 -7
- data/doc/classes/Hash.src/M000023.html +7 -5
- data/doc/classes/Hash.src/M000024.html +5 -5
- data/doc/classes/Hash.src/M000025.html +4 -4
- data/doc/classes/Hash.src/M000026.html +4 -8
- data/doc/classes/Hash.src/M000027.html +22 -0
- data/doc/classes/Hash.src/M000028.html +18 -0
- data/doc/classes/Hash.src/M000029.html +20 -0
- data/doc/classes/Hash.src/M000030.html +18 -0
- data/doc/classes/Hash.src/M000031.html +30 -0
- data/doc/classes/Hash.src/M000032.html +19 -0
- data/doc/classes/Hash.src/M000033.html +19 -0
- data/doc/classes/Hash.src/M000034.html +18 -0
- data/doc/classes/Hash.src/M000035.html +18 -0
- data/doc/classes/Hash.src/M000036.html +21 -0
- data/doc/classes/Object.html +75 -39
- data/doc/classes/Object.src/M000077.html +24 -0
- data/doc/classes/Object.src/M000078.html +19 -0
- data/doc/classes/Object.src/{M000028.html → M000079.html} +1 -1
- data/doc/classes/Object.src/{M000029.html → M000080.html} +1 -1
- data/doc/classes/Object.src/{M000030.html → M000081.html} +1 -1
- data/doc/classes/Object.src/{M000031.html → M000082.html} +1 -1
- data/doc/classes/Object.src/{M000032.html → M000083.html} +1 -1
- data/doc/classes/Object.src/{M000033.html → M000084.html} +2 -2
- data/doc/classes/OrderedArray.html +178 -0
- data/doc/classes/OrderedArray.src/M000001.html +18 -0
- data/doc/classes/OrderedArray.src/M000002.html +18 -0
- data/doc/classes/OrderedArray.src/M000003.html +18 -0
- data/doc/classes/OrderedHash.html +324 -0
- data/doc/classes/OrderedHash.src/M000064.html +19 -0
- data/doc/classes/OrderedHash.src/M000065.html +18 -0
- data/doc/classes/OrderedHash.src/M000066.html +18 -0
- data/doc/classes/OrderedHash.src/M000067.html +18 -0
- data/doc/classes/OrderedHash.src/M000068.html +18 -0
- data/doc/classes/OrderedHash.src/M000069.html +18 -0
- data/doc/classes/OrderedHash.src/M000070.html +20 -0
- data/doc/classes/OrderedHash.src/M000071.html +18 -0
- data/doc/classes/OrderedHash.src/M000072.html +18 -0
- data/doc/classes/OrderedHash.src/M000073.html +19 -0
- data/doc/classes/OrderedHash.src/M000074.html +24 -0
- data/doc/classes/{Quickbooks/Qbxml.html → Qbxml.html} +11 -13
- data/doc/classes/{Quickbooks/Qbxml → Qbxml}/Request.html +32 -22
- data/doc/classes/Qbxml/Request.src/M000184.html +65 -0
- data/doc/classes/Qbxml/Request.src/M000185.html +19 -0
- data/doc/classes/Qbxml/Request.src/M000186.html +83 -0
- data/doc/classes/{Quickbooks/Qbxml → Qbxml}/RequestSet.html +32 -26
- data/doc/classes/{Quickbooks/Connection.src/M000104.html → Qbxml/RequestSet.src/M000187.html} +7 -5
- data/doc/classes/Qbxml/RequestSet.src/M000188.html +26 -0
- data/doc/classes/Qbxml/RequestSet.src/M000189.html +18 -0
- data/doc/classes/Qbxml/RequestSet.src/M000190.html +22 -0
- data/doc/classes/{Quickbooks/Qbxml → Qbxml}/Response.html +51 -51
- data/doc/classes/Qbxml/Response.src/M000175.html +24 -0
- data/doc/classes/Qbxml/Response.src/M000176.html +19 -0
- data/doc/classes/Qbxml/Response.src/M000177.html +55 -0
- data/doc/classes/{Quickbooks/Connection.src/M000097.html → Qbxml/Response.src/M000178.html} +4 -4
- data/doc/classes/Qbxml/Response.src/M000179.html +18 -0
- data/doc/classes/Qbxml/Response.src/M000180.html +18 -0
- data/doc/classes/{Quickbooks/Connection.src/M000100.html → Qbxml/Response.src/M000181.html} +4 -4
- data/doc/classes/{Quickbooks/Connection.src/M000101.html → Qbxml/Response.src/M000182.html} +4 -4
- data/doc/classes/Qbxml/Response.src/M000183.html +63 -0
- data/doc/classes/{Quickbooks/Qbxml → Qbxml}/ResponseSet.html +47 -41
- data/doc/classes/Qbxml/ResponseSet.src/M000168.html +22 -0
- data/doc/classes/Qbxml/ResponseSet.src/M000169.html +26 -0
- data/doc/classes/Qbxml/ResponseSet.src/M000170.html +24 -0
- data/doc/classes/Qbxml/ResponseSet.src/M000171.html +20 -0
- data/doc/classes/Qbxml/ResponseSet.src/M000172.html +27 -0
- data/doc/classes/Qbxml/ResponseSet.src/M000173.html +18 -0
- data/doc/classes/Qbxml/ResponseSet.src/M000174.html +18 -0
- data/doc/classes/Quickbooks.html +24 -10
- data/doc/classes/Quickbooks/Address.html +5 -5
- data/doc/classes/Quickbooks/Address.src/{M000107.html → M000150.html} +0 -0
- data/doc/classes/Quickbooks/Base.html +133 -120
- data/doc/classes/Quickbooks/Base.src/{M000080.html → M000131.html} +1 -1
- data/doc/classes/Quickbooks/Base.src/M000132.html +20 -0
- data/doc/classes/Quickbooks/Base.src/M000133.html +19 -0
- data/doc/classes/Quickbooks/Base.src/{M000082.html → M000134.html} +1 -1
- data/doc/classes/Quickbooks/Base.src/{M000083.html → M000135.html} +2 -2
- data/doc/classes/Quickbooks/Base.src/M000136.html +30 -0
- data/doc/classes/Quickbooks/Base.src/{M000085.html → M000137.html} +1 -1
- data/doc/classes/Quickbooks/Base.src/{M000086.html → M000138.html} +2 -2
- data/doc/classes/Quickbooks/Base.src/{M000087.html → M000139.html} +2 -2
- data/doc/classes/Quickbooks/Base.src/{M000088.html → M000140.html} +2 -2
- data/doc/classes/Quickbooks/Base.src/{M000089.html → M000141.html} +1 -1
- data/doc/classes/Quickbooks/Base.src/{M000090.html → M000142.html} +1 -1
- data/doc/classes/Quickbooks/Base.src/{M000091.html → M000143.html} +1 -1
- data/doc/classes/Quickbooks/Base.src/{M000092.html → M000144.html} +3 -3
- data/doc/classes/Quickbooks/Base.src/{M000093.html → M000145.html} +2 -2
- data/doc/classes/Quickbooks/Base.src/{M000094.html → M000146.html} +2 -2
- data/doc/classes/Quickbooks/Base.src/{M000095.html → M000147.html} +1 -1
- data/doc/classes/Quickbooks/{Qbxml/ResponseSetArrayExt.html → Deleted.html} +14 -6
- data/doc/classes/Quickbooks/ListDeleted.html +139 -0
- data/doc/classes/Quickbooks/ListDeleted.src/M000149.html +18 -0
- data/doc/classes/Quickbooks/ListItem.html +11 -11
- data/doc/classes/Quickbooks/ListItem.src/M000129.html +19 -0
- data/doc/classes/Quickbooks/ListItem.src/{M000079.html → M000130.html} +4 -4
- data/doc/classes/Quickbooks/Model.html +110 -110
- data/doc/classes/Quickbooks/Model.src/{M000059.html → M000109.html} +4 -3
- data/doc/classes/Quickbooks/Model.src/{M000060.html → M000110.html} +2 -2
- data/doc/classes/Quickbooks/Model.src/{M000061.html → M000111.html} +2 -2
- data/doc/classes/Quickbooks/Model.src/{M000062.html → M000112.html} +3 -2
- data/doc/classes/Quickbooks/Model.src/{M000063.html → M000113.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/M000114.html +22 -0
- data/doc/classes/Quickbooks/Model.src/{M000065.html → M000115.html} +2 -2
- data/doc/classes/Quickbooks/Model.src/{M000066.html → M000116.html} +2 -2
- data/doc/classes/Quickbooks/Model.src/{M000067.html → M000117.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000068.html → M000118.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000069.html → M000119.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000070.html → M000120.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000071.html → M000121.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000072.html → M000122.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000073.html → M000123.html} +2 -2
- data/doc/classes/Quickbooks/Model.src/{M000074.html → M000124.html} +3 -3
- data/doc/classes/Quickbooks/Model.src/{M000075.html → M000125.html} +3 -3
- data/doc/classes/Quickbooks/Model.src/{M000076.html → M000126.html} +1 -1
- data/doc/classes/Quickbooks/Model.src/{M000077.html → M000127.html} +1 -1
- data/doc/classes/{QBHelpers.html → Quickbooks/OleAdapter.html} +19 -9
- data/doc/classes/Quickbooks/{Connection.html → OleAdapter/Connection.html} +80 -106
- data/doc/classes/Quickbooks/{Qbxml/Response.src/M000044.html → OleAdapter/Connection.src/M000094.html} +4 -4
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000095.html +19 -0
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000096.html +24 -0
- data/doc/classes/Quickbooks/{Qbxml/Response.src/M000047.html → OleAdapter/Connection.src/M000097.html} +4 -4
- data/doc/classes/Quickbooks/{Qbxml/Response.src/M000048.html → OleAdapter/Connection.src/M000098.html} +4 -4
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000099.html +21 -0
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000100.html +24 -0
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000101.html +20 -0
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000102.html +24 -0
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000103.html +24 -0
- data/doc/classes/{QBHelpers → Quickbooks/OleAdapter}/Ole.html +24 -24
- data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000104.html +21 -0
- data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000105.html +22 -0
- data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000106.html +18 -0
- data/doc/classes/Quickbooks/{Qbxml/RequestSetArrayExt.html → QbxmlDebugAdapter.html} +11 -5
- data/doc/classes/Quickbooks/QbxmlDebugAdapter/Connection.html +139 -0
- data/doc/classes/Quickbooks/{Qbxml/RequestSet.src/M000055.html → QbxmlDebugAdapter/Connection.src/M000093.html} +4 -4
- data/doc/classes/Quickbooks/Ref.html +5 -5
- data/doc/classes/Quickbooks/Ref.src/{M000096.html → M000148.html} +0 -0
- data/doc/classes/Quickbooks/Transaction.html +10 -10
- data/doc/classes/Quickbooks/Transaction.src/{M000057.html → M000107.html} +0 -0
- data/doc/classes/Quickbooks/Transaction.src/{M000058.html → M000108.html} +0 -0
- data/doc/classes/Quickbooks/TxnDeleted.html +139 -0
- data/doc/classes/Quickbooks/TxnDeleted.src/M000128.html +18 -0
- data/doc/classes/SlashedArray.html +226 -0
- data/doc/classes/SlashedArray.src/M000161.html +23 -0
- data/doc/classes/SlashedArray.src/M000162.html +18 -0
- data/doc/classes/SlashedArray.src/M000163.html +18 -0
- data/doc/classes/SlashedArray.src/M000164.html +22 -0
- data/doc/classes/SlashedArray.src/M000165.html +22 -0
- data/doc/classes/SlashedArray.src/M000166.html +18 -0
- data/doc/classes/SlashedArray.src/M000167.html +22 -0
- data/doc/classes/SlashedHash.html +193 -0
- data/doc/classes/SlashedHash.src/M000156.html +22 -0
- data/doc/classes/SlashedHash.src/M000157.html +18 -0
- data/doc/classes/SlashedHash.src/M000158.html +18 -0
- data/doc/classes/SlashedHash.src/M000159.html +27 -0
- data/doc/classes/SlashedHash.src/M000160.html +22 -0
- data/doc/classes/String.html +269 -0
- data/doc/classes/String.src/M000085.html +18 -0
- data/doc/classes/String.src/M000086.html +18 -0
- data/doc/classes/String.src/M000087.html +18 -0
- data/doc/classes/String.src/M000088.html +18 -0
- data/doc/classes/String.src/M000089.html +18 -0
- data/doc/classes/String.src/M000090.html +18 -0
- data/doc/classes/String.src/M000091.html +18 -0
- data/doc/classes/String.src/M000092.html +97 -0
- data/doc/classes/UniqueArray.html +193 -0
- data/doc/classes/UniqueArray.src/M000151.html +25 -0
- data/doc/classes/UniqueArray.src/M000152.html +18 -0
- data/doc/classes/UniqueArray.src/M000153.html +20 -0
- data/doc/classes/UniqueArray.src/M000154.html +20 -0
- data/doc/classes/UniqueArray.src/M000155.html +20 -0
- data/doc/created.rid +1 -1
- data/doc/files/LICENSE.html +2 -2
- data/doc/files/lib/{quickbooks/connection_rb.html → qbxml/request_rb.html} +6 -6
- data/doc/files/lib/{quickbooks/qbxml_rb.html → qbxml/response_rb.html} +6 -6
- data/doc/files/lib/{quickbooks/qbxml/request_rb.html → qbxml/support_rb.html} +6 -7
- data/doc/files/lib/qbxml_rb.html +109 -0
- data/doc/files/lib/quickbooks/{qbxml/response_rb.html → adapters/ole_adapter_rb.html} +5 -5
- data/doc/files/lib/quickbooks/adapters/qbxml_debug_adapter_rb.html +108 -0
- data/doc/files/lib/quickbooks/base_rb.html +2 -4
- data/doc/files/lib/quickbooks/model_rb.html +2 -1
- data/doc/files/lib/quickbooks/models/customer_rb.html +1 -1
- data/doc/files/lib/quickbooks/models/deleted_rb.html +101 -0
- data/doc/files/lib/quickbooks/models/list_item_rb.html +1 -1
- data/doc/files/lib/quickbooks/ruby_magic_rb.html +9 -1
- data/doc/files/lib/quickbooks/{ole_helper_rb.html → structure_rb.html} +20 -7
- data/doc/files/lib/quickbooks_rb.html +2 -3
- data/doc/fr_class_index.html +19 -10
- data/doc/fr_file_index.html +8 -5
- data/doc/fr_method_index.html +190 -110
- data/lib/qbxml.rb +2 -0
- data/lib/qbxml/request.rb +205 -0
- data/lib/qbxml/response.rb +197 -0
- data/lib/qbxml/support.rb +130 -0
- data/lib/quickbooks.rb +1 -2
- data/lib/quickbooks/adapters/ole_adapter.rb +148 -0
- data/lib/quickbooks/adapters/qbxml_debug_adapter.rb +10 -0
- data/lib/quickbooks/base.rb +33 -24
- data/lib/quickbooks/model.rb +20 -13
- data/lib/quickbooks/models/customer.rb +1 -1
- data/lib/quickbooks/models/deleted.rb +22 -0
- data/lib/quickbooks/models/list_item.rb +29 -27
- data/lib/quickbooks/ruby_magic.rb +31 -28
- data/lib/quickbooks/structure.rb +393 -0
- metadata +242 -127
- data/doc/classes/Class.src/M000027.html +0 -18
- data/doc/classes/QBHelpers/Ole.src/M000108.html +0 -21
- data/doc/classes/QBHelpers/Ole.src/M000109.html +0 -22
- data/doc/classes/QBHelpers/Ole.src/M000110.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000081.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000084.html +0 -23
- data/doc/classes/Quickbooks/Connection.src/M000098.html +0 -19
- data/doc/classes/Quickbooks/Connection.src/M000099.html +0 -24
- data/doc/classes/Quickbooks/Connection.src/M000102.html +0 -21
- data/doc/classes/Quickbooks/Connection.src/M000103.html +0 -24
- data/doc/classes/Quickbooks/Connection.src/M000105.html +0 -24
- data/doc/classes/Quickbooks/Connection.src/M000106.html +0 -24
- data/doc/classes/Quickbooks/ListItem.src/M000078.html +0 -19
- data/doc/classes/Quickbooks/Model.src/M000064.html +0 -18
- data/doc/classes/Quickbooks/Qbxml/Request.src/M000050.html +0 -34
- data/doc/classes/Quickbooks/Qbxml/Request.src/M000051.html +0 -19
- data/doc/classes/Quickbooks/Qbxml/Request.src/M000052.html +0 -81
- data/doc/classes/Quickbooks/Qbxml/RequestSet.src/M000053.html +0 -22
- data/doc/classes/Quickbooks/Qbxml/RequestSet.src/M000054.html +0 -26
- data/doc/classes/Quickbooks/Qbxml/RequestSet.src/M000056.html +0 -22
- data/doc/classes/Quickbooks/Qbxml/Response.src/M000041.html +0 -24
- data/doc/classes/Quickbooks/Qbxml/Response.src/M000042.html +0 -19
- data/doc/classes/Quickbooks/Qbxml/Response.src/M000043.html +0 -44
- data/doc/classes/Quickbooks/Qbxml/Response.src/M000045.html +0 -18
- data/doc/classes/Quickbooks/Qbxml/Response.src/M000046.html +0 -18
- data/doc/classes/Quickbooks/Qbxml/Response.src/M000049.html +0 -63
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000034.html +0 -22
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000035.html +0 -26
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000036.html +0 -24
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000037.html +0 -18
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000038.html +0 -27
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000039.html +0 -18
- data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000040.html +0 -18
- data/lib/quickbooks/connection.rb +0 -105
- data/lib/quickbooks/ole_helper.rb +0 -47
- data/lib/quickbooks/qbxml.rb +0 -2
- data/lib/quickbooks/qbxml/request.rb +0 -169
- data/lib/quickbooks/qbxml/response.rb +0 -185
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'qbxml/support'
|
2
|
+
require 'formatted_string'
|
3
|
+
|
4
|
+
module Qbxml
|
5
|
+
# module ResponseSetArrayExt
|
6
|
+
# end
|
7
|
+
|
8
|
+
class ResponseSet
|
9
|
+
include Enumerable
|
10
|
+
def set
|
11
|
+
unless @set.is_a?(Array)
|
12
|
+
@set = []
|
13
|
+
# @set.extend(Qbxml::ResponseSetArrayExt)
|
14
|
+
end
|
15
|
+
@set
|
16
|
+
end
|
17
|
+
delegate_methods [:each, :length, :first, :last, :[], :map, :join] => :set
|
18
|
+
def <<(qbxml_response)
|
19
|
+
if qbxml_response.is_a?(Qbxml::Response)
|
20
|
+
set << qbxml_response
|
21
|
+
elsif qbxml_response.respond_to?(:each)
|
22
|
+
qbxml_response.each do |response|
|
23
|
+
self << response
|
24
|
+
end
|
25
|
+
else
|
26
|
+
raise ArgumentError, "Cannot add object of type #{qbxml_response.class.name} to a Qbxml::ResponseSet"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(xml_or_hash)
|
31
|
+
if(xml_or_hash.is_a?(Hash))
|
32
|
+
self.append_from_hash(xml_or_hash)
|
33
|
+
elsif(xml_or_hash.is_a?(String))
|
34
|
+
self.append_from_xml(xml_or_hash)
|
35
|
+
else
|
36
|
+
raise ArgumentError, "Qbxml::ResponseSet must be initialized with either a Hash or an xml-formatted String."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def append_from_xml(xml)
|
41
|
+
# puts "ResponseXML:"
|
42
|
+
# puts xml
|
43
|
+
self.append_from_hash(xml.formatted(:xml).to_hash)
|
44
|
+
end
|
45
|
+
def append_from_hash(hsh)
|
46
|
+
to_append = []
|
47
|
+
hsh = hsh['QBXML'] if hsh.has_key?('QBXML')
|
48
|
+
hsh = hsh['QBXMLMsgsRs'] if hsh.has_key?('QBXMLMsgsRs')
|
49
|
+
# responses will contain one or more keys.
|
50
|
+
hsh.each_key do |name|
|
51
|
+
# response_type is either a single response object, or an array of response objects. Force it into an array:
|
52
|
+
responses = hsh[name].is_a?(Array) ? hsh[name] : [hsh[name]]
|
53
|
+
responses.each { |response| to_append << Response.new(name => response) }
|
54
|
+
end
|
55
|
+
self << to_append
|
56
|
+
end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
def from_xml(xml)
|
60
|
+
new.append_from_xml(xml)
|
61
|
+
end
|
62
|
+
def from_hash(hsh)
|
63
|
+
new.append_from_hash(hsh)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Response
|
69
|
+
attr_accessor :response_type, :status, :message, :severity, :ret_items
|
70
|
+
# For Development purposes:
|
71
|
+
attr_accessor :raw_response
|
72
|
+
|
73
|
+
def initialize(xml_or_hash)
|
74
|
+
if(xml_or_hash.is_a?(Hash))
|
75
|
+
self.import_from_hash(xml_or_hash)
|
76
|
+
elsif(xml_or_hash.is_a?(String))
|
77
|
+
self.import_from_xml(xml_or_hash)
|
78
|
+
else
|
79
|
+
raise ArgumentError, "Qbxml::ResponseSet must be initialized with either a Hash or an xml-formatted String."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def import_from_xml(xml)
|
84
|
+
self.import_from_hash(xml.formatted(:xml).to_hash)
|
85
|
+
self
|
86
|
+
end
|
87
|
+
def import_from_hash(hsh)
|
88
|
+
raise ArgumentError, "Hash passed to Qbxml::Response.from_hash must contain only one top-level key" unless hsh.keys.length == 1
|
89
|
+
name = hsh.keys.first
|
90
|
+
# for development
|
91
|
+
self.raw_response = hsh
|
92
|
+
# * * * *
|
93
|
+
hsh = hsh[name]
|
94
|
+
|
95
|
+
self.status = hsh['statusCode'].to_i
|
96
|
+
self.severity = hsh['statusSeverity']
|
97
|
+
self.message = hsh['statusMessage']
|
98
|
+
# if self.status == 0 # Status is good, proceed with eating the request.
|
99
|
+
# <ListDeletedQueryRs requestID="5" statusCode="0" statusSeverity="Info" statusMessage="Status OK">
|
100
|
+
# <ListDeletedRet>
|
101
|
+
# <ListDelType>Customer</ListDelType>
|
102
|
+
# <ListID>80000030-1203622308</ListID>
|
103
|
+
# <TimeCreated>2008-02-21T14:31:48-05:00</TimeCreated>
|
104
|
+
# <TimeDeleted>2008-03-18T17:31:12-05:00</TimeDeleted>
|
105
|
+
# <FullName>Rachel Parker</FullName>
|
106
|
+
# </ListDeletedRet>
|
107
|
+
# </ListDeletedQueryRs>
|
108
|
+
if m = name.match(/^(List|Txn)Del(etedQuery)?Rs$/)
|
109
|
+
# (List|Txn)DelRs, or (List|Txn)DeletedQueryRs - both return just a few attributes, like ListID / TxnID and TimeDeleted
|
110
|
+
list_or_txn = m[1]
|
111
|
+
long_name = m[1]+'Del'+m[2].to_s
|
112
|
+
ret_key = long_name.gsub(/Query$/,'')+'Ret'
|
113
|
+
self.ret_items = hsh[ret_key].is_a?(Array) ? hsh[ret_key] : [hsh[ret_key]].compact # Force to be an array - it's return items!
|
114
|
+
self.response_type = self.ret_items.empty? ? m[1] : self.ret_items[0][list_or_txn+'DelType']
|
115
|
+
elsif m = name.match(/^((?:[A-Za-z][a-z]+)+)(Query|Mod|Add)Rs$/)
|
116
|
+
self.response_type = m[1]
|
117
|
+
self.ret_items = hsh[self.response_type+'Ret']
|
118
|
+
else
|
119
|
+
raise "Could not read this response:\n#{self.raw_response.inspect}"
|
120
|
+
end
|
121
|
+
# else # Status is bad.
|
122
|
+
|
123
|
+
# end
|
124
|
+
# puts self.inspect
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
class << self
|
130
|
+
def from_xml(xml)
|
131
|
+
new.import_from_xml(xml)
|
132
|
+
end
|
133
|
+
def from_hash(hsh)
|
134
|
+
new.import_from_hash(hsh)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def instantiatable? # Just checks to see if it can create an object of this type, and if there is actually data to instantiate
|
139
|
+
self.response_type ? (Quickbooks.const_defined?(self.response_type) && self.ret_items.is_a?(Hash) || (self.ret_items.is_a?(Array) && self.ret_items[0].is_a?(Hash))) : false
|
140
|
+
end
|
141
|
+
def success?
|
142
|
+
self.status == 0
|
143
|
+
end
|
144
|
+
def error?
|
145
|
+
!success?
|
146
|
+
end
|
147
|
+
|
148
|
+
def instantiate(reinstantiate=nil)
|
149
|
+
objs = []
|
150
|
+
(self.ret_items.is_a?(Array) ? self.ret_items : [self.ret_items]).each do |ret_item|
|
151
|
+
obj = reinstantiate if reinstantiate
|
152
|
+
if instantiatable?
|
153
|
+
if self.status == 0
|
154
|
+
if obj.nil?
|
155
|
+
obj = "Quickbooks::#{self.response_type}".constantize.instantiate(ret_item)
|
156
|
+
else
|
157
|
+
obj.class.instantiate(obj, ret_item)
|
158
|
+
end
|
159
|
+
else
|
160
|
+
# Instantiatable, but some error status. For any error status
|
161
|
+
if obj.nil? # Must be a new object. Just as well, create a new object WITHOUT any original_attributes.
|
162
|
+
obj = "Quickbooks::#{self.response_type}".constantize.new(ret_item)
|
163
|
+
else # An existing object. Must be an update or delete request. Update object's original_attributes.
|
164
|
+
updated = []
|
165
|
+
ret_item.each do |k,v|
|
166
|
+
k = k.underscore
|
167
|
+
if obj.original_values[k] != v
|
168
|
+
updated << k
|
169
|
+
if obj.class.instance_variable_get('@object_properties').has_key?(k.to_sym)
|
170
|
+
obj.original_values[k] = obj.class.instance_variable_get('@object_properties')[k.to_sym].new(v)
|
171
|
+
else
|
172
|
+
obj.original_values[k] = v
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
# Update object's 'read-only' attributes (as well as in the original_values):
|
177
|
+
obj.class.read_only.stringify_values.camelize_values.each do |k|
|
178
|
+
obj.send(k.underscore + '=', ret_item[k]) if ret_item.has_key?(k) && obj.respond_to?(k.underscore + '=')
|
179
|
+
end
|
180
|
+
self.message = self.message + " Other properties were out of date: [" + updated.join(', ') + '].'
|
181
|
+
end
|
182
|
+
obj.errors << {:code => self.status, :message => self.message, :response => self}
|
183
|
+
end
|
184
|
+
else
|
185
|
+
if self.status == 0
|
186
|
+
obj.errors << {:code => nil, :message => "Cannot instantiate object of type #{self.response_type}!", :response => self}
|
187
|
+
else
|
188
|
+
obj.errors << {:code => self.status, :message => self.message, :response => self}
|
189
|
+
end
|
190
|
+
end
|
191
|
+
obj.response_log << self unless obj.nil?
|
192
|
+
objs << obj
|
193
|
+
end
|
194
|
+
objs.length > 1 ? objs : objs[0] # Single or nil if not more than one.
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
gem 'formattedstring'
|
2
|
+
gem 'builder'
|
3
|
+
require 'quickbooks/structure'
|
4
|
+
|
5
|
+
class Object
|
6
|
+
# This allows one to effectively 'proxy' specific methods to be called on the return value of one of its methods.
|
7
|
+
# For example, obj.length could be delegated to do the same thing as obj.full_text.length
|
8
|
+
def delegate_methods(hsh)
|
9
|
+
raise ArgumentError, "delegate_methods should be called like: delegate_methods [:method1, :method2] => :delegated_to_method" unless hsh.keys.first.is_a?(Array)
|
10
|
+
methods = hsh.keys.first
|
11
|
+
delegate_to = hsh[methods]
|
12
|
+
methods.each do |method|
|
13
|
+
self.send(:eval, <<-ddddddd
|
14
|
+
def #{method}(*args, &block)
|
15
|
+
block_given? ? self.#{delegate_to}.#{method}(*args, &block) : self.#{delegate_to}.#{method}(*args)
|
16
|
+
end
|
17
|
+
ddddddd
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Normally one would say, "if [:a, :b, :c].include?(:a)" -- which is backward thinking, instead you should use this magic:
|
23
|
+
# ":a.is_one_of?(:a, :b, :c)", or :a.is_one_of?([:a, :b, :c]).
|
24
|
+
def is_one_of?(*ary)
|
25
|
+
raise ArgumentError, "exists_in? requires an array to be passed" unless ary.is_a?(Array)
|
26
|
+
ary.flatten.include?(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Class
|
31
|
+
def lone_name
|
32
|
+
name.gsub(/.*::/, '')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class String
|
37
|
+
def constantize
|
38
|
+
Object.module_eval("::#{self}", __FILE__, __LINE__)
|
39
|
+
end
|
40
|
+
|
41
|
+
def underscore
|
42
|
+
gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
43
|
+
end
|
44
|
+
|
45
|
+
def camelize
|
46
|
+
gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Array
|
51
|
+
def camelize_values(specials={})
|
52
|
+
self.dup.camelize_values!(specials)
|
53
|
+
end
|
54
|
+
def camelize_values!(specials={})
|
55
|
+
self.each_with_index do |v,i|
|
56
|
+
self[i] = specials.has_key?(v) ? specials[v] : (v.is_a?(Symbol) ? v.to_s.camelize.to_sym : v.camelize)
|
57
|
+
end
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def stringify_values
|
62
|
+
self.dup.stringify_values!
|
63
|
+
end
|
64
|
+
def stringify_values!
|
65
|
+
self.each_with_index { |v,i| self[i] = v.to_s }
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def only(*values)
|
70
|
+
self.dup.only!(*values)
|
71
|
+
end
|
72
|
+
def only!(*values)
|
73
|
+
values.flatten!
|
74
|
+
i = 0
|
75
|
+
while i <= length-1 do
|
76
|
+
self[i].is_one_of?(values) ? i += 1 : self.slice!(i)
|
77
|
+
end
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def order(*ordered)
|
82
|
+
self.dup.order!(*ordered)
|
83
|
+
end
|
84
|
+
def order!(*ordered)
|
85
|
+
self.replace(ordered.flatten!.only!(self))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class Hash
|
90
|
+
# Transform all the keys in the hash to CamelCase format.
|
91
|
+
def camelize_keys(specials={})
|
92
|
+
self.dup.camelize_keys!(specials)
|
93
|
+
end
|
94
|
+
def camelize_keys!(specials={})
|
95
|
+
self.each_key do |k|
|
96
|
+
self[specials.has_key?(k) ? specials[k] : k.camelize] = self.delete(k)
|
97
|
+
end
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def stringify_keys(specials={})
|
102
|
+
self.dup.stringify_keys!(specials)
|
103
|
+
end
|
104
|
+
def stringify_keys!(specials={})
|
105
|
+
self.each_key do |k|
|
106
|
+
self[specials.has_key?(k) ? specials[k] : k.to_s] = self.delete(k)
|
107
|
+
end
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
def only(*keys)
|
112
|
+
self.dup.only!(*keys)
|
113
|
+
end
|
114
|
+
def only!(*keys)
|
115
|
+
keys = keys.flatten
|
116
|
+
self.keys.each { |k| self.delete(k) unless keys.include?(k) }
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
def transform_keys(trans_hash)
|
121
|
+
self.dup.transform_keys!(trans_hash)
|
122
|
+
end
|
123
|
+
def transform_keys!(trans_hash)
|
124
|
+
raise ArgumentError, "transform_keys takes a single hash argument" unless trans_hash.is_a?(Hash)
|
125
|
+
self.each_key do |k|
|
126
|
+
self[trans_hash.has_key?(k) ? trans_hash[k] : k] = self.delete(k)
|
127
|
+
end
|
128
|
+
self
|
129
|
+
end
|
130
|
+
end
|
data/lib/quickbooks.rb
CHANGED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'win32ole'
|
2
|
+
|
3
|
+
module Quickbooks
|
4
|
+
# Connection is used internally by Quickbooks::Base to automatically manage a the communication with quickbooks.
|
5
|
+
# Currently the only connection mode supported is WIN32OlE, which means your application must be running on the
|
6
|
+
# same computer as Quickbooks.
|
7
|
+
#
|
8
|
+
# Quickbooks does not allow the user to close the company or exit the program until all outside applications are
|
9
|
+
# disconnected from its API. Therefore, this class includes an at_exit hook that automatically closes all open
|
10
|
+
# connections for you when your program exits.
|
11
|
+
module OleAdapter
|
12
|
+
class Ole
|
13
|
+
# Simply holds the actual OLE object.
|
14
|
+
attr_reader :ole
|
15
|
+
|
16
|
+
# Pass in the OLE name of the application you want connected to, and the name of a type library, if you need one.
|
17
|
+
def initialize(ole_app, type_library=nil)
|
18
|
+
@ole_app = ole_app
|
19
|
+
@type_library = type_library
|
20
|
+
@ole = WIN32OLE.new(ole_app)
|
21
|
+
self.classes
|
22
|
+
end
|
23
|
+
|
24
|
+
# Finds an OLE variable in the OLE type library, if you specified one in new().
|
25
|
+
# This navigates the OLE classes and constants for you and returns the variable that matches the _var_name_ you specify.
|
26
|
+
# This is used with Quickbooks to get the qbFileOpenDoNotCare parameter to pass to the OpenConnection2 method:
|
27
|
+
# @quickbooks = Ole.new('QBXMLRP2.RequestProcessor', 'QBXMLRP2 1.0 Type Library')
|
28
|
+
# @quickbooks.OpenConnection2('','Sample Application',@quickbooks.get_variable('localQBD'))
|
29
|
+
# @session = @quickbooks.BeginSession('',@quickbooks.get_variable('qbFileOpenDoNotCare'))
|
30
|
+
# ...
|
31
|
+
def get_variable(var_name)
|
32
|
+
return nil unless @type_library
|
33
|
+
self.classes.each do |class_name|
|
34
|
+
found = self.constant_for(class_name.name).variables.find {|var| var.name == var_name}
|
35
|
+
return found if found
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def classes #:nodoc:
|
40
|
+
return nil unless @type_library
|
41
|
+
@classes ||= WIN32OLE_TYPE.ole_classes(@type_library)
|
42
|
+
end
|
43
|
+
|
44
|
+
def constant_for(class_name) #:nodoc:
|
45
|
+
return nil unless @type_library
|
46
|
+
@constant_for ||= {}
|
47
|
+
@constant_for[class_name] ||= WIN32OLE_TYPE.new(@type_library, class_name)
|
48
|
+
end
|
49
|
+
|
50
|
+
# method_missing sends all other methods to the OLE object, so you can treat this object as your OLE object.
|
51
|
+
def method_missing(method_name, *args)
|
52
|
+
@ole.send(method_name, *args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Connection
|
57
|
+
class << self #:nodoc: all
|
58
|
+
def connections
|
59
|
+
@connections || (@connections = [])
|
60
|
+
end
|
61
|
+
def connections=(v)
|
62
|
+
# raise ArgumentError, "Quickbooks::Connection.connections can only contain Quickbooks::Connection objects, but contains #{v.collect {|c| c.class.name}.uniq.join(', ')} objects" unless v.collect {|c| c.class.name}.uniq == ['Quickbooks::Connection']
|
63
|
+
@connections = v
|
64
|
+
end
|
65
|
+
|
66
|
+
at_exit do
|
67
|
+
Connection.connections.each do |conn|
|
68
|
+
conn.close
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Initializes an instance of Quickbooks::Connection.
|
74
|
+
# - _application_name_ is required.
|
75
|
+
# - _file_ is optional, in which case the connection will be made to the currently open company file in the Quickbooks application.
|
76
|
+
# - _user_ and _password_ may be required if you have specified a specific file to open.
|
77
|
+
# - _connection_type_ can be one of: ['unknown', 'localQBD', 'remoteQBD', 'localQBDLaunchUI', 'remoteQBOE']
|
78
|
+
# - _connection_mode_ can be one of: ['SingleUser', 'MultiUser', 'DoNotCare']
|
79
|
+
def initialize(application_name='RubyApplication', file='', user='', password='', connection_type='localQBD', connection_mode='DoNotCare')
|
80
|
+
@file = file
|
81
|
+
@user = user
|
82
|
+
@password = password
|
83
|
+
@application_name = application_name
|
84
|
+
@quickbooks = Ole.new('QBXMLRP2.RequestProcessor', 'QBXMLRP2 1.0 Type Library')
|
85
|
+
@connection_type = @quickbooks.get_variable(connection_type)
|
86
|
+
@connection_mode = @quickbooks.get_variable('qbFileOpen'+connection_mode)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns true if there is an open connection to Quickbooks, false if not. Use session? to determine an open session.
|
90
|
+
def connected?
|
91
|
+
@connected ||= false
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns true if there is an active session. Use connected? to determine whether you are connected or not.
|
95
|
+
def session?
|
96
|
+
!@session.nil?
|
97
|
+
end
|
98
|
+
|
99
|
+
# Sends a request to Quickbooks. This request should be a valid QBXML request. Use Qbxml::Request to generate valid requests.
|
100
|
+
def send_xml(xml)
|
101
|
+
@quickbooks.ProcessRequest(session, xml)
|
102
|
+
rescue => e
|
103
|
+
warn "ERROR processing request:\n#{xml}"
|
104
|
+
raise # Reraises the original error, only this way we got the xml output
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the active connection to Quickbooks, or creates a new one if none exists.
|
108
|
+
def connection
|
109
|
+
@connection || begin
|
110
|
+
@connection = @quickbooks.ole
|
111
|
+
@connection.OpenConnection2('',@application_name,@connection_type)
|
112
|
+
Connection.connections << self
|
113
|
+
@connected = true
|
114
|
+
@connection
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Begin a session to Quickbooks.
|
119
|
+
def session
|
120
|
+
@session || begin
|
121
|
+
@session = connection.BeginSession(@file,@connection_mode)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# End the current Quickbooks session. After ending a session, a new session may be reopened if desired.
|
126
|
+
def end_session
|
127
|
+
if !@session.nil?
|
128
|
+
connection.EndSession(@session)
|
129
|
+
@session = nil
|
130
|
+
true
|
131
|
+
else
|
132
|
+
false
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Close the connection to Quickbooks. Automatically ends the session, if there is one.
|
137
|
+
def close
|
138
|
+
end_session
|
139
|
+
if connected? && connection.CloseConnection
|
140
|
+
@connected = false
|
141
|
+
@connection = nil
|
142
|
+
Quickbooks::Connection.connections = Quickbooks::Connection.connections - [self]
|
143
|
+
end
|
144
|
+
return !@connected # Returns false if CloseConnection failed.
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|