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.
Files changed (294) hide show
  1. data/LICENSE +1 -1
  2. data/Rakefile +4 -2
  3. data/doc/classes/Array.html +333 -40
  4. data/doc/classes/Array.src/M000037.html +18 -0
  5. data/doc/classes/Array.src/M000038.html +21 -0
  6. data/doc/classes/Array.src/M000039.html +18 -0
  7. data/doc/classes/Array.src/M000040.html +19 -0
  8. data/doc/classes/Array.src/M000041.html +18 -0
  9. data/doc/classes/Array.src/{M000004.html → M000042.html} +1 -1
  10. data/doc/classes/Array.src/M000043.html +18 -0
  11. data/doc/classes/Array.src/M000044.html +18 -0
  12. data/doc/classes/Array.src/{M000001.html → M000045.html} +1 -1
  13. data/doc/classes/Array.src/{M000002.html → M000046.html} +1 -1
  14. data/doc/classes/Array.src/{M000003.html → M000047.html} +1 -1
  15. data/doc/classes/Array.src/M000048.html +23 -0
  16. data/doc/classes/Array.src/{M000005.html → M000049.html} +1 -1
  17. data/doc/classes/Array.src/{M000006.html → M000050.html} +2 -2
  18. data/doc/classes/Array.src/{M000007.html → M000051.html} +1 -1
  19. data/doc/classes/Array.src/{M000008.html → M000052.html} +1 -1
  20. data/doc/classes/Array.src/M000053.html +18 -0
  21. data/doc/classes/Array.src/M000054.html +20 -0
  22. data/doc/classes/Array.src/M000055.html +18 -0
  23. data/doc/classes/Array.src/M000056.html +34 -0
  24. data/doc/classes/Array.src/M000057.html +19 -0
  25. data/doc/classes/Array.src/M000058.html +29 -0
  26. data/doc/classes/Array.src/M000059.html +18 -0
  27. data/doc/classes/Array.src/M000060.html +20 -0
  28. data/doc/classes/Array.src/M000061.html +18 -0
  29. data/doc/classes/Array.src/M000062.html +18 -0
  30. data/doc/classes/Array.src/M000063.html +19 -0
  31. data/doc/classes/Class.html +25 -6
  32. data/doc/classes/Class.src/M000075.html +18 -0
  33. data/doc/classes/Class.src/M000076.html +18 -0
  34. data/doc/classes/Hash.html +329 -103
  35. data/doc/classes/Hash.src/M000004.html +18 -0
  36. data/doc/classes/Hash.src/M000005.html +21 -0
  37. data/doc/classes/Hash.src/M000006.html +18 -0
  38. data/doc/classes/Hash.src/M000007.html +21 -0
  39. data/doc/classes/Hash.src/M000008.html +18 -0
  40. data/doc/classes/Hash.src/M000009.html +6 -4
  41. data/doc/classes/Hash.src/M000010.html +4 -7
  42. data/doc/classes/Hash.src/M000011.html +8 -4
  43. data/doc/classes/Hash.src/M000012.html +4 -7
  44. data/doc/classes/Hash.src/M000013.html +7 -4
  45. data/doc/classes/Hash.src/M000014.html +4 -7
  46. data/doc/classes/Hash.src/M000015.html +6 -12
  47. data/doc/classes/Hash.src/M000016.html +4 -6
  48. data/doc/classes/Hash.src/M000017.html +7 -4
  49. data/doc/classes/Hash.src/M000018.html +4 -6
  50. data/doc/classes/Hash.src/M000019.html +5 -22
  51. data/doc/classes/Hash.src/M000020.html +14 -5
  52. data/doc/classes/Hash.src/M000021.html +7 -5
  53. data/doc/classes/Hash.src/M000022.html +5 -7
  54. data/doc/classes/Hash.src/M000023.html +7 -5
  55. data/doc/classes/Hash.src/M000024.html +5 -5
  56. data/doc/classes/Hash.src/M000025.html +4 -4
  57. data/doc/classes/Hash.src/M000026.html +4 -8
  58. data/doc/classes/Hash.src/M000027.html +22 -0
  59. data/doc/classes/Hash.src/M000028.html +18 -0
  60. data/doc/classes/Hash.src/M000029.html +20 -0
  61. data/doc/classes/Hash.src/M000030.html +18 -0
  62. data/doc/classes/Hash.src/M000031.html +30 -0
  63. data/doc/classes/Hash.src/M000032.html +19 -0
  64. data/doc/classes/Hash.src/M000033.html +19 -0
  65. data/doc/classes/Hash.src/M000034.html +18 -0
  66. data/doc/classes/Hash.src/M000035.html +18 -0
  67. data/doc/classes/Hash.src/M000036.html +21 -0
  68. data/doc/classes/Object.html +75 -39
  69. data/doc/classes/Object.src/M000077.html +24 -0
  70. data/doc/classes/Object.src/M000078.html +19 -0
  71. data/doc/classes/Object.src/{M000028.html → M000079.html} +1 -1
  72. data/doc/classes/Object.src/{M000029.html → M000080.html} +1 -1
  73. data/doc/classes/Object.src/{M000030.html → M000081.html} +1 -1
  74. data/doc/classes/Object.src/{M000031.html → M000082.html} +1 -1
  75. data/doc/classes/Object.src/{M000032.html → M000083.html} +1 -1
  76. data/doc/classes/Object.src/{M000033.html → M000084.html} +2 -2
  77. data/doc/classes/OrderedArray.html +178 -0
  78. data/doc/classes/OrderedArray.src/M000001.html +18 -0
  79. data/doc/classes/OrderedArray.src/M000002.html +18 -0
  80. data/doc/classes/OrderedArray.src/M000003.html +18 -0
  81. data/doc/classes/OrderedHash.html +324 -0
  82. data/doc/classes/OrderedHash.src/M000064.html +19 -0
  83. data/doc/classes/OrderedHash.src/M000065.html +18 -0
  84. data/doc/classes/OrderedHash.src/M000066.html +18 -0
  85. data/doc/classes/OrderedHash.src/M000067.html +18 -0
  86. data/doc/classes/OrderedHash.src/M000068.html +18 -0
  87. data/doc/classes/OrderedHash.src/M000069.html +18 -0
  88. data/doc/classes/OrderedHash.src/M000070.html +20 -0
  89. data/doc/classes/OrderedHash.src/M000071.html +18 -0
  90. data/doc/classes/OrderedHash.src/M000072.html +18 -0
  91. data/doc/classes/OrderedHash.src/M000073.html +19 -0
  92. data/doc/classes/OrderedHash.src/M000074.html +24 -0
  93. data/doc/classes/{Quickbooks/Qbxml.html → Qbxml.html} +11 -13
  94. data/doc/classes/{Quickbooks/Qbxml → Qbxml}/Request.html +32 -22
  95. data/doc/classes/Qbxml/Request.src/M000184.html +65 -0
  96. data/doc/classes/Qbxml/Request.src/M000185.html +19 -0
  97. data/doc/classes/Qbxml/Request.src/M000186.html +83 -0
  98. data/doc/classes/{Quickbooks/Qbxml → Qbxml}/RequestSet.html +32 -26
  99. data/doc/classes/{Quickbooks/Connection.src/M000104.html → Qbxml/RequestSet.src/M000187.html} +7 -5
  100. data/doc/classes/Qbxml/RequestSet.src/M000188.html +26 -0
  101. data/doc/classes/Qbxml/RequestSet.src/M000189.html +18 -0
  102. data/doc/classes/Qbxml/RequestSet.src/M000190.html +22 -0
  103. data/doc/classes/{Quickbooks/Qbxml → Qbxml}/Response.html +51 -51
  104. data/doc/classes/Qbxml/Response.src/M000175.html +24 -0
  105. data/doc/classes/Qbxml/Response.src/M000176.html +19 -0
  106. data/doc/classes/Qbxml/Response.src/M000177.html +55 -0
  107. data/doc/classes/{Quickbooks/Connection.src/M000097.html → Qbxml/Response.src/M000178.html} +4 -4
  108. data/doc/classes/Qbxml/Response.src/M000179.html +18 -0
  109. data/doc/classes/Qbxml/Response.src/M000180.html +18 -0
  110. data/doc/classes/{Quickbooks/Connection.src/M000100.html → Qbxml/Response.src/M000181.html} +4 -4
  111. data/doc/classes/{Quickbooks/Connection.src/M000101.html → Qbxml/Response.src/M000182.html} +4 -4
  112. data/doc/classes/Qbxml/Response.src/M000183.html +63 -0
  113. data/doc/classes/{Quickbooks/Qbxml → Qbxml}/ResponseSet.html +47 -41
  114. data/doc/classes/Qbxml/ResponseSet.src/M000168.html +22 -0
  115. data/doc/classes/Qbxml/ResponseSet.src/M000169.html +26 -0
  116. data/doc/classes/Qbxml/ResponseSet.src/M000170.html +24 -0
  117. data/doc/classes/Qbxml/ResponseSet.src/M000171.html +20 -0
  118. data/doc/classes/Qbxml/ResponseSet.src/M000172.html +27 -0
  119. data/doc/classes/Qbxml/ResponseSet.src/M000173.html +18 -0
  120. data/doc/classes/Qbxml/ResponseSet.src/M000174.html +18 -0
  121. data/doc/classes/Quickbooks.html +24 -10
  122. data/doc/classes/Quickbooks/Address.html +5 -5
  123. data/doc/classes/Quickbooks/Address.src/{M000107.html → M000150.html} +0 -0
  124. data/doc/classes/Quickbooks/Base.html +133 -120
  125. data/doc/classes/Quickbooks/Base.src/{M000080.html → M000131.html} +1 -1
  126. data/doc/classes/Quickbooks/Base.src/M000132.html +20 -0
  127. data/doc/classes/Quickbooks/Base.src/M000133.html +19 -0
  128. data/doc/classes/Quickbooks/Base.src/{M000082.html → M000134.html} +1 -1
  129. data/doc/classes/Quickbooks/Base.src/{M000083.html → M000135.html} +2 -2
  130. data/doc/classes/Quickbooks/Base.src/M000136.html +30 -0
  131. data/doc/classes/Quickbooks/Base.src/{M000085.html → M000137.html} +1 -1
  132. data/doc/classes/Quickbooks/Base.src/{M000086.html → M000138.html} +2 -2
  133. data/doc/classes/Quickbooks/Base.src/{M000087.html → M000139.html} +2 -2
  134. data/doc/classes/Quickbooks/Base.src/{M000088.html → M000140.html} +2 -2
  135. data/doc/classes/Quickbooks/Base.src/{M000089.html → M000141.html} +1 -1
  136. data/doc/classes/Quickbooks/Base.src/{M000090.html → M000142.html} +1 -1
  137. data/doc/classes/Quickbooks/Base.src/{M000091.html → M000143.html} +1 -1
  138. data/doc/classes/Quickbooks/Base.src/{M000092.html → M000144.html} +3 -3
  139. data/doc/classes/Quickbooks/Base.src/{M000093.html → M000145.html} +2 -2
  140. data/doc/classes/Quickbooks/Base.src/{M000094.html → M000146.html} +2 -2
  141. data/doc/classes/Quickbooks/Base.src/{M000095.html → M000147.html} +1 -1
  142. data/doc/classes/Quickbooks/{Qbxml/ResponseSetArrayExt.html → Deleted.html} +14 -6
  143. data/doc/classes/Quickbooks/ListDeleted.html +139 -0
  144. data/doc/classes/Quickbooks/ListDeleted.src/M000149.html +18 -0
  145. data/doc/classes/Quickbooks/ListItem.html +11 -11
  146. data/doc/classes/Quickbooks/ListItem.src/M000129.html +19 -0
  147. data/doc/classes/Quickbooks/ListItem.src/{M000079.html → M000130.html} +4 -4
  148. data/doc/classes/Quickbooks/Model.html +110 -110
  149. data/doc/classes/Quickbooks/Model.src/{M000059.html → M000109.html} +4 -3
  150. data/doc/classes/Quickbooks/Model.src/{M000060.html → M000110.html} +2 -2
  151. data/doc/classes/Quickbooks/Model.src/{M000061.html → M000111.html} +2 -2
  152. data/doc/classes/Quickbooks/Model.src/{M000062.html → M000112.html} +3 -2
  153. data/doc/classes/Quickbooks/Model.src/{M000063.html → M000113.html} +1 -1
  154. data/doc/classes/Quickbooks/Model.src/M000114.html +22 -0
  155. data/doc/classes/Quickbooks/Model.src/{M000065.html → M000115.html} +2 -2
  156. data/doc/classes/Quickbooks/Model.src/{M000066.html → M000116.html} +2 -2
  157. data/doc/classes/Quickbooks/Model.src/{M000067.html → M000117.html} +1 -1
  158. data/doc/classes/Quickbooks/Model.src/{M000068.html → M000118.html} +1 -1
  159. data/doc/classes/Quickbooks/Model.src/{M000069.html → M000119.html} +1 -1
  160. data/doc/classes/Quickbooks/Model.src/{M000070.html → M000120.html} +1 -1
  161. data/doc/classes/Quickbooks/Model.src/{M000071.html → M000121.html} +1 -1
  162. data/doc/classes/Quickbooks/Model.src/{M000072.html → M000122.html} +1 -1
  163. data/doc/classes/Quickbooks/Model.src/{M000073.html → M000123.html} +2 -2
  164. data/doc/classes/Quickbooks/Model.src/{M000074.html → M000124.html} +3 -3
  165. data/doc/classes/Quickbooks/Model.src/{M000075.html → M000125.html} +3 -3
  166. data/doc/classes/Quickbooks/Model.src/{M000076.html → M000126.html} +1 -1
  167. data/doc/classes/Quickbooks/Model.src/{M000077.html → M000127.html} +1 -1
  168. data/doc/classes/{QBHelpers.html → Quickbooks/OleAdapter.html} +19 -9
  169. data/doc/classes/Quickbooks/{Connection.html → OleAdapter/Connection.html} +80 -106
  170. data/doc/classes/Quickbooks/{Qbxml/Response.src/M000044.html → OleAdapter/Connection.src/M000094.html} +4 -4
  171. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000095.html +19 -0
  172. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000096.html +24 -0
  173. data/doc/classes/Quickbooks/{Qbxml/Response.src/M000047.html → OleAdapter/Connection.src/M000097.html} +4 -4
  174. data/doc/classes/Quickbooks/{Qbxml/Response.src/M000048.html → OleAdapter/Connection.src/M000098.html} +4 -4
  175. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000099.html +21 -0
  176. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000100.html +24 -0
  177. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000101.html +20 -0
  178. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000102.html +24 -0
  179. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000103.html +24 -0
  180. data/doc/classes/{QBHelpers → Quickbooks/OleAdapter}/Ole.html +24 -24
  181. data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000104.html +21 -0
  182. data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000105.html +22 -0
  183. data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000106.html +18 -0
  184. data/doc/classes/Quickbooks/{Qbxml/RequestSetArrayExt.html → QbxmlDebugAdapter.html} +11 -5
  185. data/doc/classes/Quickbooks/QbxmlDebugAdapter/Connection.html +139 -0
  186. data/doc/classes/Quickbooks/{Qbxml/RequestSet.src/M000055.html → QbxmlDebugAdapter/Connection.src/M000093.html} +4 -4
  187. data/doc/classes/Quickbooks/Ref.html +5 -5
  188. data/doc/classes/Quickbooks/Ref.src/{M000096.html → M000148.html} +0 -0
  189. data/doc/classes/Quickbooks/Transaction.html +10 -10
  190. data/doc/classes/Quickbooks/Transaction.src/{M000057.html → M000107.html} +0 -0
  191. data/doc/classes/Quickbooks/Transaction.src/{M000058.html → M000108.html} +0 -0
  192. data/doc/classes/Quickbooks/TxnDeleted.html +139 -0
  193. data/doc/classes/Quickbooks/TxnDeleted.src/M000128.html +18 -0
  194. data/doc/classes/SlashedArray.html +226 -0
  195. data/doc/classes/SlashedArray.src/M000161.html +23 -0
  196. data/doc/classes/SlashedArray.src/M000162.html +18 -0
  197. data/doc/classes/SlashedArray.src/M000163.html +18 -0
  198. data/doc/classes/SlashedArray.src/M000164.html +22 -0
  199. data/doc/classes/SlashedArray.src/M000165.html +22 -0
  200. data/doc/classes/SlashedArray.src/M000166.html +18 -0
  201. data/doc/classes/SlashedArray.src/M000167.html +22 -0
  202. data/doc/classes/SlashedHash.html +193 -0
  203. data/doc/classes/SlashedHash.src/M000156.html +22 -0
  204. data/doc/classes/SlashedHash.src/M000157.html +18 -0
  205. data/doc/classes/SlashedHash.src/M000158.html +18 -0
  206. data/doc/classes/SlashedHash.src/M000159.html +27 -0
  207. data/doc/classes/SlashedHash.src/M000160.html +22 -0
  208. data/doc/classes/String.html +269 -0
  209. data/doc/classes/String.src/M000085.html +18 -0
  210. data/doc/classes/String.src/M000086.html +18 -0
  211. data/doc/classes/String.src/M000087.html +18 -0
  212. data/doc/classes/String.src/M000088.html +18 -0
  213. data/doc/classes/String.src/M000089.html +18 -0
  214. data/doc/classes/String.src/M000090.html +18 -0
  215. data/doc/classes/String.src/M000091.html +18 -0
  216. data/doc/classes/String.src/M000092.html +97 -0
  217. data/doc/classes/UniqueArray.html +193 -0
  218. data/doc/classes/UniqueArray.src/M000151.html +25 -0
  219. data/doc/classes/UniqueArray.src/M000152.html +18 -0
  220. data/doc/classes/UniqueArray.src/M000153.html +20 -0
  221. data/doc/classes/UniqueArray.src/M000154.html +20 -0
  222. data/doc/classes/UniqueArray.src/M000155.html +20 -0
  223. data/doc/created.rid +1 -1
  224. data/doc/files/LICENSE.html +2 -2
  225. data/doc/files/lib/{quickbooks/connection_rb.html → qbxml/request_rb.html} +6 -6
  226. data/doc/files/lib/{quickbooks/qbxml_rb.html → qbxml/response_rb.html} +6 -6
  227. data/doc/files/lib/{quickbooks/qbxml/request_rb.html → qbxml/support_rb.html} +6 -7
  228. data/doc/files/lib/qbxml_rb.html +109 -0
  229. data/doc/files/lib/quickbooks/{qbxml/response_rb.html → adapters/ole_adapter_rb.html} +5 -5
  230. data/doc/files/lib/quickbooks/adapters/qbxml_debug_adapter_rb.html +108 -0
  231. data/doc/files/lib/quickbooks/base_rb.html +2 -4
  232. data/doc/files/lib/quickbooks/model_rb.html +2 -1
  233. data/doc/files/lib/quickbooks/models/customer_rb.html +1 -1
  234. data/doc/files/lib/quickbooks/models/deleted_rb.html +101 -0
  235. data/doc/files/lib/quickbooks/models/list_item_rb.html +1 -1
  236. data/doc/files/lib/quickbooks/ruby_magic_rb.html +9 -1
  237. data/doc/files/lib/quickbooks/{ole_helper_rb.html → structure_rb.html} +20 -7
  238. data/doc/files/lib/quickbooks_rb.html +2 -3
  239. data/doc/fr_class_index.html +19 -10
  240. data/doc/fr_file_index.html +8 -5
  241. data/doc/fr_method_index.html +190 -110
  242. data/lib/qbxml.rb +2 -0
  243. data/lib/qbxml/request.rb +205 -0
  244. data/lib/qbxml/response.rb +197 -0
  245. data/lib/qbxml/support.rb +130 -0
  246. data/lib/quickbooks.rb +1 -2
  247. data/lib/quickbooks/adapters/ole_adapter.rb +148 -0
  248. data/lib/quickbooks/adapters/qbxml_debug_adapter.rb +10 -0
  249. data/lib/quickbooks/base.rb +33 -24
  250. data/lib/quickbooks/model.rb +20 -13
  251. data/lib/quickbooks/models/customer.rb +1 -1
  252. data/lib/quickbooks/models/deleted.rb +22 -0
  253. data/lib/quickbooks/models/list_item.rb +29 -27
  254. data/lib/quickbooks/ruby_magic.rb +31 -28
  255. data/lib/quickbooks/structure.rb +393 -0
  256. metadata +242 -127
  257. data/doc/classes/Class.src/M000027.html +0 -18
  258. data/doc/classes/QBHelpers/Ole.src/M000108.html +0 -21
  259. data/doc/classes/QBHelpers/Ole.src/M000109.html +0 -22
  260. data/doc/classes/QBHelpers/Ole.src/M000110.html +0 -18
  261. data/doc/classes/Quickbooks/Base.src/M000081.html +0 -18
  262. data/doc/classes/Quickbooks/Base.src/M000084.html +0 -23
  263. data/doc/classes/Quickbooks/Connection.src/M000098.html +0 -19
  264. data/doc/classes/Quickbooks/Connection.src/M000099.html +0 -24
  265. data/doc/classes/Quickbooks/Connection.src/M000102.html +0 -21
  266. data/doc/classes/Quickbooks/Connection.src/M000103.html +0 -24
  267. data/doc/classes/Quickbooks/Connection.src/M000105.html +0 -24
  268. data/doc/classes/Quickbooks/Connection.src/M000106.html +0 -24
  269. data/doc/classes/Quickbooks/ListItem.src/M000078.html +0 -19
  270. data/doc/classes/Quickbooks/Model.src/M000064.html +0 -18
  271. data/doc/classes/Quickbooks/Qbxml/Request.src/M000050.html +0 -34
  272. data/doc/classes/Quickbooks/Qbxml/Request.src/M000051.html +0 -19
  273. data/doc/classes/Quickbooks/Qbxml/Request.src/M000052.html +0 -81
  274. data/doc/classes/Quickbooks/Qbxml/RequestSet.src/M000053.html +0 -22
  275. data/doc/classes/Quickbooks/Qbxml/RequestSet.src/M000054.html +0 -26
  276. data/doc/classes/Quickbooks/Qbxml/RequestSet.src/M000056.html +0 -22
  277. data/doc/classes/Quickbooks/Qbxml/Response.src/M000041.html +0 -24
  278. data/doc/classes/Quickbooks/Qbxml/Response.src/M000042.html +0 -19
  279. data/doc/classes/Quickbooks/Qbxml/Response.src/M000043.html +0 -44
  280. data/doc/classes/Quickbooks/Qbxml/Response.src/M000045.html +0 -18
  281. data/doc/classes/Quickbooks/Qbxml/Response.src/M000046.html +0 -18
  282. data/doc/classes/Quickbooks/Qbxml/Response.src/M000049.html +0 -63
  283. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000034.html +0 -22
  284. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000035.html +0 -26
  285. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000036.html +0 -24
  286. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000037.html +0 -18
  287. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000038.html +0 -27
  288. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000039.html +0 -18
  289. data/doc/classes/Quickbooks/Qbxml/ResponseSet.src/M000040.html +0 -18
  290. data/lib/quickbooks/connection.rb +0 -105
  291. data/lib/quickbooks/ole_helper.rb +0 -47
  292. data/lib/quickbooks/qbxml.rb +0 -2
  293. data/lib/quickbooks/qbxml/request.rb +0 -169
  294. 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
@@ -1,7 +1,6 @@
1
- require 'rubygems'
2
- require 'quickbooks/connection'
3
1
  require 'quickbooks/base'
4
2
  require 'quickbooks/models/list_item'
5
3
  require 'quickbooks/models/transaction'
6
4
 
7
5
  require 'quickbooks/models/customer'
6
+ require 'quickbooks/models/deleted'
@@ -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