quickbooks 0.4.0 → 0.9.9

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 (293) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +23 -0
  3. data/License.txt +54 -0
  4. data/Manifest.txt +73 -0
  5. data/README.txt +79 -0
  6. data/Rakefile +17 -78
  7. data/lib/quickbooks.rb +153 -7
  8. data/lib/quickbooks/adaptability.rb +67 -0
  9. data/lib/quickbooks/adapters/http_adapter.rb +94 -0
  10. data/lib/quickbooks/adapters/https_adapter.rb +57 -0
  11. data/lib/quickbooks/adapters/ole_adapter.rb +141 -110
  12. data/lib/quickbooks/adapters/spew_adapter.rb +39 -0
  13. data/lib/quickbooks/adapters/tcp_adapter.rb +71 -0
  14. data/lib/quickbooks/adapters/test_adapter.rb +62 -0
  15. data/lib/quickbooks/element.rb +385 -0
  16. data/lib/quickbooks/element_collection.rb +105 -0
  17. data/lib/quickbooks/extlib.rb +8 -0
  18. data/lib/quickbooks/extlib/assertions.rb +8 -0
  19. data/lib/quickbooks/extlib/class.rb +98 -0
  20. data/lib/quickbooks/extlib/days_and_times.rb +10 -0
  21. data/lib/quickbooks/extlib/days_and_times/duration.rb +362 -0
  22. data/lib/quickbooks/extlib/days_and_times/numeric.rb +48 -0
  23. data/lib/quickbooks/extlib/days_and_times/object.rb +19 -0
  24. data/lib/quickbooks/extlib/days_and_times/time.rb +137 -0
  25. data/lib/quickbooks/extlib/hash.rb +327 -0
  26. data/lib/quickbooks/extlib/hook.rb +366 -0
  27. data/lib/quickbooks/extlib/inflection.rb +436 -0
  28. data/lib/quickbooks/extlib/logger.rb +202 -0
  29. data/lib/quickbooks/extlib/object.rb +162 -0
  30. data/lib/quickbooks/extlib/pathname.rb +15 -0
  31. data/lib/quickbooks/extlib/rubygems.rb +38 -0
  32. data/lib/quickbooks/extlib/string.rb +32 -0
  33. data/lib/quickbooks/extlib/time.rb +41 -0
  34. data/lib/quickbooks/model.rb +503 -121
  35. data/lib/quickbooks/option.rb +95 -0
  36. data/lib/quickbooks/property.rb +69 -0
  37. data/lib/quickbooks/ruby_ext.rb +251 -0
  38. data/lib/quickbooks/type.rb +75 -0
  39. data/lib/quickbooks/types.rb +58 -0
  40. data/lib/quickbooks/version.rb +10 -0
  41. data/lib/quickbooks/xsd.rb +243 -0
  42. data/lib/quickbooks/xsd/attribute.rb +57 -0
  43. data/lib/quickbooks/xsd/choice.rb +94 -0
  44. data/lib/quickbooks/xsd/complex_type.rb +77 -0
  45. data/lib/quickbooks/xsd/element.rb +214 -0
  46. data/lib/quickbooks/xsd/group.rb +94 -0
  47. data/lib/quickbooks/xsd/restriction.rb +51 -0
  48. data/lib/quickbooks/xsd/sequence.rb +85 -0
  49. data/lib/quickbooks/xsd/simple_type.rb +87 -0
  50. data/lib/quickbooks/xsd/union.rb +70 -0
  51. data/lib/quickbooks/xsd/validation.rb +89 -0
  52. data/lib/quickbooks/xsd/xml_parse.rb +80 -0
  53. data/quickbooks.gemspec +36 -0
  54. data/source/qbxml21_demo.xsd +2223 -0
  55. data/source/qbxmlops_demo.xsd +483 -0
  56. data/source/qbxmltypes.xsd +160 -0
  57. data/spec/association_spec.rb +5 -0
  58. data/spec/element_collection_spec.rb +8 -0
  59. data/spec/find_spec.rb +30 -0
  60. data/spec/lib/quickbooks/element_spec.rb +83 -0
  61. data/spec/lib/quickbooks/elements/sales_order_add_spec.rb +14 -0
  62. data/spec/lib/quickbooks/elements/vendor_add_spec.rb +78 -0
  63. data/spec/lib/quickbooks/model_spec.rb +89 -0
  64. data/spec/lib/quickbooks/models/customer_spec.rb +52 -0
  65. data/spec/lib/quickbooks/models/invoice_spec.rb +12 -0
  66. data/spec/lib/quickbooks/models/sales_order_line_spec.rb +0 -0
  67. data/spec/lib/quickbooks/models/sales_order_spec.rb +145 -0
  68. data/spec/lib/quickbooks/xsd/choice_spec.rb +18 -0
  69. data/spec/pending_spec.rb +11 -0
  70. data/spec/quickbooks_spec.rb +38 -0
  71. data/spec/repeatable_spec.rb +20 -0
  72. data/spec/requires_spec.rb +10 -0
  73. data/spec/spec_helper.rb +5 -0
  74. data/spec/validation_spec.rb +24 -0
  75. metadata +133 -285
  76. metadata.gz.sig +0 -0
  77. data/LICENSE +0 -16
  78. data/README +0 -49
  79. data/doc/classes/Array.html +0 -368
  80. data/doc/classes/Array.src/M000026.html +0 -18
  81. data/doc/classes/Array.src/M000027.html +0 -21
  82. data/doc/classes/Array.src/M000028.html +0 -18
  83. data/doc/classes/Array.src/M000029.html +0 -19
  84. data/doc/classes/Array.src/M000030.html +0 -18
  85. data/doc/classes/Array.src/M000031.html +0 -23
  86. data/doc/classes/Array.src/M000032.html +0 -18
  87. data/doc/classes/Array.src/M000033.html +0 -18
  88. data/doc/classes/Array.src/M000034.html +0 -18
  89. data/doc/classes/Array.src/M000035.html +0 -19
  90. data/doc/classes/Array.src/M000036.html +0 -18
  91. data/doc/classes/Array.src/M000037.html +0 -23
  92. data/doc/classes/Array.src/M000038.html +0 -18
  93. data/doc/classes/Array.src/M000039.html +0 -21
  94. data/doc/classes/Array.src/M000040.html +0 -18
  95. data/doc/classes/Array.src/M000041.html +0 -18
  96. data/doc/classes/Class.html +0 -171
  97. data/doc/classes/Class.src/M000042.html +0 -18
  98. data/doc/classes/Class.src/M000043.html +0 -18
  99. data/doc/classes/Hash.html +0 -516
  100. data/doc/classes/Hash.src/M000001.html +0 -18
  101. data/doc/classes/Hash.src/M000002.html +0 -21
  102. data/doc/classes/Hash.src/M000003.html +0 -18
  103. data/doc/classes/Hash.src/M000004.html +0 -21
  104. data/doc/classes/Hash.src/M000005.html +0 -18
  105. data/doc/classes/Hash.src/M000006.html +0 -20
  106. data/doc/classes/Hash.src/M000007.html +0 -18
  107. data/doc/classes/Hash.src/M000008.html +0 -22
  108. data/doc/classes/Hash.src/M000009.html +0 -18
  109. data/doc/classes/Hash.src/M000010.html +0 -21
  110. data/doc/classes/Hash.src/M000011.html +0 -24
  111. data/doc/classes/Hash.src/M000012.html +0 -18
  112. data/doc/classes/Hash.src/M000013.html +0 -21
  113. data/doc/classes/Hash.src/M000014.html +0 -18
  114. data/doc/classes/Hash.src/M000015.html +0 -21
  115. data/doc/classes/Hash.src/M000016.html +0 -18
  116. data/doc/classes/Hash.src/M000017.html +0 -21
  117. data/doc/classes/Hash.src/M000018.html +0 -27
  118. data/doc/classes/Hash.src/M000019.html +0 -20
  119. data/doc/classes/Hash.src/M000020.html +0 -18
  120. data/doc/classes/Hash.src/M000021.html +0 -18
  121. data/doc/classes/Hash.src/M000022.html +0 -18
  122. data/doc/classes/Hash.src/M000023.html +0 -18
  123. data/doc/classes/Hash.src/M000024.html +0 -18
  124. data/doc/classes/Hash.src/M000025.html +0 -28
  125. data/doc/classes/Object.html +0 -278
  126. data/doc/classes/Object.src/M000044.html +0 -24
  127. data/doc/classes/Object.src/M000045.html +0 -19
  128. data/doc/classes/Object.src/M000046.html +0 -24
  129. data/doc/classes/Object.src/M000047.html +0 -18
  130. data/doc/classes/Object.src/M000048.html +0 -19
  131. data/doc/classes/Object.src/M000049.html +0 -18
  132. data/doc/classes/Object.src/M000050.html +0 -18
  133. data/doc/classes/Object.src/M000051.html +0 -18
  134. data/doc/classes/Qbxml.html +0 -131
  135. data/doc/classes/Qbxml/Request.html +0 -224
  136. data/doc/classes/Qbxml/Request.src/M000132.html +0 -66
  137. data/doc/classes/Qbxml/Request.src/M000133.html +0 -19
  138. data/doc/classes/Qbxml/Request.src/M000134.html +0 -83
  139. data/doc/classes/Qbxml/RequestSet.html +0 -199
  140. data/doc/classes/Qbxml/RequestSet.src/M000135.html +0 -22
  141. data/doc/classes/Qbxml/RequestSet.src/M000136.html +0 -26
  142. data/doc/classes/Qbxml/RequestSet.src/M000137.html +0 -18
  143. data/doc/classes/Qbxml/RequestSet.src/M000138.html +0 -22
  144. data/doc/classes/Qbxml/Response.html +0 -302
  145. data/doc/classes/Qbxml/Response.src/M000123.html +0 -24
  146. data/doc/classes/Qbxml/Response.src/M000124.html +0 -19
  147. data/doc/classes/Qbxml/Response.src/M000125.html +0 -55
  148. data/doc/classes/Qbxml/Response.src/M000126.html +0 -18
  149. data/doc/classes/Qbxml/Response.src/M000127.html +0 -18
  150. data/doc/classes/Qbxml/Response.src/M000128.html +0 -18
  151. data/doc/classes/Qbxml/Response.src/M000129.html +0 -18
  152. data/doc/classes/Qbxml/Response.src/M000130.html +0 -18
  153. data/doc/classes/Qbxml/Response.src/M000131.html +0 -63
  154. data/doc/classes/Qbxml/ResponseSet.html +0 -244
  155. data/doc/classes/Qbxml/ResponseSet.src/M000116.html +0 -22
  156. data/doc/classes/Qbxml/ResponseSet.src/M000117.html +0 -26
  157. data/doc/classes/Qbxml/ResponseSet.src/M000118.html +0 -24
  158. data/doc/classes/Qbxml/ResponseSet.src/M000119.html +0 -20
  159. data/doc/classes/Qbxml/ResponseSet.src/M000120.html +0 -27
  160. data/doc/classes/Qbxml/ResponseSet.src/M000121.html +0 -18
  161. data/doc/classes/Qbxml/ResponseSet.src/M000122.html +0 -18
  162. data/doc/classes/Quickbooks.html +0 -196
  163. data/doc/classes/Quickbooks/Address.html +0 -139
  164. data/doc/classes/Quickbooks/Address.src/M000115.html +0 -19
  165. data/doc/classes/Quickbooks/Base.html +0 -567
  166. data/doc/classes/Quickbooks/Base.src/M000095.html +0 -18
  167. data/doc/classes/Quickbooks/Base.src/M000096.html +0 -20
  168. data/doc/classes/Quickbooks/Base.src/M000097.html +0 -19
  169. data/doc/classes/Quickbooks/Base.src/M000098.html +0 -18
  170. data/doc/classes/Quickbooks/Base.src/M000099.html +0 -19
  171. data/doc/classes/Quickbooks/Base.src/M000100.html +0 -30
  172. data/doc/classes/Quickbooks/Base.src/M000101.html +0 -22
  173. data/doc/classes/Quickbooks/Base.src/M000102.html +0 -30
  174. data/doc/classes/Quickbooks/Base.src/M000103.html +0 -19
  175. data/doc/classes/Quickbooks/Base.src/M000104.html +0 -19
  176. data/doc/classes/Quickbooks/Base.src/M000105.html +0 -18
  177. data/doc/classes/Quickbooks/Base.src/M000106.html +0 -18
  178. data/doc/classes/Quickbooks/Base.src/M000107.html +0 -19
  179. data/doc/classes/Quickbooks/Base.src/M000108.html +0 -18
  180. data/doc/classes/Quickbooks/Base.src/M000109.html +0 -45
  181. data/doc/classes/Quickbooks/Base.src/M000110.html +0 -18
  182. data/doc/classes/Quickbooks/Base.src/M000111.html +0 -18
  183. data/doc/classes/Quickbooks/Base.src/M000112.html +0 -20
  184. data/doc/classes/Quickbooks/BillAddress.html +0 -113
  185. data/doc/classes/Quickbooks/CreditCardInfo.html +0 -113
  186. data/doc/classes/Quickbooks/Customer.html +0 -113
  187. data/doc/classes/Quickbooks/CustomerTypeRef.html +0 -113
  188. data/doc/classes/Quickbooks/Deleted.html +0 -113
  189. data/doc/classes/Quickbooks/ItemSalesTaxRef.html +0 -113
  190. data/doc/classes/Quickbooks/JobTypeRef.html +0 -113
  191. data/doc/classes/Quickbooks/ListDeleted.html +0 -139
  192. data/doc/classes/Quickbooks/ListDeleted.src/M000114.html +0 -18
  193. data/doc/classes/Quickbooks/ListItem.html +0 -170
  194. data/doc/classes/Quickbooks/ListItem.src/M000093.html +0 -20
  195. data/doc/classes/Quickbooks/ListItem.src/M000094.html +0 -18
  196. data/doc/classes/Quickbooks/Model.html +0 -462
  197. data/doc/classes/Quickbooks/Model.src/M000073.html +0 -24
  198. data/doc/classes/Quickbooks/Model.src/M000074.html +0 -19
  199. data/doc/classes/Quickbooks/Model.src/M000075.html +0 -18
  200. data/doc/classes/Quickbooks/Model.src/M000076.html +0 -18
  201. data/doc/classes/Quickbooks/Model.src/M000077.html +0 -18
  202. data/doc/classes/Quickbooks/Model.src/M000078.html +0 -22
  203. data/doc/classes/Quickbooks/Model.src/M000079.html +0 -32
  204. data/doc/classes/Quickbooks/Model.src/M000080.html +0 -32
  205. data/doc/classes/Quickbooks/Model.src/M000081.html +0 -18
  206. data/doc/classes/Quickbooks/Model.src/M000082.html +0 -18
  207. data/doc/classes/Quickbooks/Model.src/M000083.html +0 -22
  208. data/doc/classes/Quickbooks/Model.src/M000084.html +0 -23
  209. data/doc/classes/Quickbooks/Model.src/M000085.html +0 -18
  210. data/doc/classes/Quickbooks/Model.src/M000086.html +0 -21
  211. data/doc/classes/Quickbooks/Model.src/M000087.html +0 -26
  212. data/doc/classes/Quickbooks/Model.src/M000088.html +0 -26
  213. data/doc/classes/Quickbooks/Model.src/M000089.html +0 -26
  214. data/doc/classes/Quickbooks/Model.src/M000090.html +0 -21
  215. data/doc/classes/Quickbooks/Model.src/M000091.html +0 -23
  216. data/doc/classes/Quickbooks/OleAdapter.html +0 -129
  217. data/doc/classes/Quickbooks/OleAdapter/Connection.html +0 -343
  218. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000058.html +0 -18
  219. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000059.html +0 -19
  220. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000060.html +0 -24
  221. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000061.html +0 -18
  222. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000062.html +0 -18
  223. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000063.html +0 -21
  224. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000064.html +0 -24
  225. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000065.html +0 -20
  226. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000066.html +0 -24
  227. data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000067.html +0 -24
  228. data/doc/classes/Quickbooks/OleAdapter/Ole.html +0 -209
  229. data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000068.html +0 -21
  230. data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000069.html +0 -22
  231. data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000070.html +0 -18
  232. data/doc/classes/Quickbooks/ParentRef.html +0 -113
  233. data/doc/classes/Quickbooks/PreferredPaymentMethodRef.html +0 -113
  234. data/doc/classes/Quickbooks/PriceLevelRef.html +0 -113
  235. data/doc/classes/Quickbooks/QbxmlDebugAdapter.html +0 -111
  236. data/doc/classes/Quickbooks/QbxmlDebugAdapter/Connection.html +0 -139
  237. data/doc/classes/Quickbooks/QbxmlDebugAdapter/Connection.src/M000057.html +0 -18
  238. data/doc/classes/Quickbooks/Ref.html +0 -146
  239. data/doc/classes/Quickbooks/Ref.src/M000113.html +0 -18
  240. data/doc/classes/Quickbooks/SalesRepRef.html +0 -113
  241. data/doc/classes/Quickbooks/SalesTaxCodeRef.html +0 -113
  242. data/doc/classes/Quickbooks/ShipAddress.html +0 -113
  243. data/doc/classes/Quickbooks/TermsRef.html +0 -113
  244. data/doc/classes/Quickbooks/Transaction.html +0 -154
  245. data/doc/classes/Quickbooks/Transaction.src/M000071.html +0 -19
  246. data/doc/classes/Quickbooks/Transaction.src/M000072.html +0 -18
  247. data/doc/classes/Quickbooks/TxnDeleted.html +0 -139
  248. data/doc/classes/Quickbooks/TxnDeleted.src/M000092.html +0 -18
  249. data/doc/classes/String.html +0 -203
  250. data/doc/classes/String.src/M000052.html +0 -18
  251. data/doc/classes/String.src/M000053.html +0 -18
  252. data/doc/classes/String.src/M000054.html +0 -18
  253. data/doc/classes/String.src/M000055.html +0 -18
  254. data/doc/classes/String.src/M000056.html +0 -18
  255. data/doc/created.rid +0 -1
  256. data/doc/files/LICENSE.html +0 -129
  257. data/doc/files/README.html +0 -225
  258. data/doc/files/lib/qbxml/request_rb.html +0 -110
  259. data/doc/files/lib/qbxml/response_rb.html +0 -109
  260. data/doc/files/lib/qbxml/support_rb.html +0 -101
  261. data/doc/files/lib/qbxml_rb.html +0 -122
  262. data/doc/files/lib/quickbooks/adapters/ole_adapter_rb.html +0 -108
  263. data/doc/files/lib/quickbooks/adapters/qbxml_debug_adapter_rb.html +0 -108
  264. data/doc/files/lib/quickbooks/base_rb.html +0 -327
  265. data/doc/files/lib/quickbooks/model_rb.html +0 -108
  266. data/doc/files/lib/quickbooks/models/common/address_rb.html +0 -101
  267. data/doc/files/lib/quickbooks/models/common/all_refs_rb.html +0 -101
  268. data/doc/files/lib/quickbooks/models/customer/credit_card_info_rb.html +0 -101
  269. data/doc/files/lib/quickbooks/models/customer_rb.html +0 -110
  270. data/doc/files/lib/quickbooks/models/deleted_rb.html +0 -101
  271. data/doc/files/lib/quickbooks/models/list_item_rb.html +0 -101
  272. data/doc/files/lib/quickbooks/models/transaction_rb.html +0 -101
  273. data/doc/files/lib/quickbooks/ruby_magic_rb.html +0 -120
  274. data/doc/files/lib/quickbooks_rb.html +0 -125
  275. data/doc/fr_class_index.html +0 -64
  276. data/doc/fr_file_index.html +0 -45
  277. data/doc/fr_method_index.html +0 -164
  278. data/doc/index.html +0 -24
  279. data/doc/rdoc-style.css +0 -208
  280. data/lib/qbxml.rb +0 -3
  281. data/lib/qbxml/request.rb +0 -207
  282. data/lib/qbxml/response.rb +0 -197
  283. data/lib/qbxml/support.rb +0 -130
  284. data/lib/quickbooks/adapters/qbxml_debug_adapter.rb +0 -10
  285. data/lib/quickbooks/base.rb +0 -277
  286. data/lib/quickbooks/models/common/address.rb +0 -14
  287. data/lib/quickbooks/models/common/all_refs.rb +0 -37
  288. data/lib/quickbooks/models/customer.rb +0 -70
  289. data/lib/quickbooks/models/customer/credit_card_info.rb +0 -5
  290. data/lib/quickbooks/models/deleted.rb +0 -22
  291. data/lib/quickbooks/models/list_item.rb +0 -41
  292. data/lib/quickbooks/models/transaction.rb +0 -49
  293. data/lib/quickbooks/ruby_magic.rb +0 -213
@@ -0,0 +1,95 @@
1
+ module Quickbooks
2
+ # A collection of Option objects. Can validate that a given object contains all required options and allowed values in this collection.
3
+ class Options
4
+ def self.from_xsd(xsd)
5
+ options = new
6
+ # puts "Options from xsd: #{xsd.inspect}"
7
+ xsd.type.items.select {|i| i.class == Quickbooks::XSD::Attribute}.each do |option_xsd|
8
+ options << Option.from_xsd(option_xsd)
9
+ end
10
+ options
11
+ end
12
+
13
+ def <<(option)
14
+ options << option
15
+ end
16
+
17
+ def validate(object)
18
+ puts "Validating #{object.inspect}!" if $DEBUG
19
+ options.check_all? { |option| option.validate(object) }
20
+ end
21
+
22
+ def include?(name)
23
+ options.any? {|option| option.name == name}
24
+ end
25
+
26
+ def defaults
27
+ options.inject({}) {|h,option| h[option.name.to_s] = option.default if option.default && option.required?; h}
28
+ end
29
+
30
+ def [](name)
31
+ name = name.to_s
32
+ options.select {|option| option.name == name}[0]
33
+ end
34
+
35
+ def delete(name)
36
+ options.reject! {|a| a.name == name}
37
+ end
38
+
39
+ private
40
+
41
+ def options
42
+ @options ||= []
43
+ end
44
+ end
45
+
46
+ # An Option is a tag attribute. Not all Elements have them. They might include things like :iterator or :iteratorID, or :onError instructions. Can validate that a given object conforms to the Option's spec.
47
+ class Option
48
+ attr_reader :name, :type
49
+ attr_accessor :default # This way we can set our own defaults
50
+
51
+ def self.from_xsd(xsd)
52
+ #<Quickbooks::XSD::Attribute:0x18005ec @use=nil, @default=nil, @type="MACROTYPE", @name="defMacro">
53
+ new(xsd.name, xsd.type, xsd.default, xsd.use)
54
+ end
55
+
56
+ def initialize(name, type, default, use)
57
+ @name = name
58
+ @type = type
59
+ @default = default
60
+ @use = use
61
+ end
62
+
63
+ def required?
64
+ @use == 'required'
65
+ end
66
+
67
+ def inspect #:nodoc:
68
+ "<Option #{@name}#{@default ? " default="+@default.inspect : ''}#{@use ? ' '+@use.upcase : ''} #{@type.inspect}>"
69
+ end
70
+
71
+ # Validates that the given object conforms to the Option's spec.
72
+ def validate(object)
73
+ errors = (object.respond_to?(:errors) ? object.errors : [])
74
+ if required? && object[@name].nil?
75
+ errors << "#{object.class.short_name} requires the #{@name} option."
76
+ return false
77
+ end
78
+ # True if there is a value and it's valid, or if there is no value.
79
+ if object[@name].nil?
80
+ true
81
+ else
82
+ if @type
83
+ if @type.validate({object[@name] => true})
84
+ true
85
+ else
86
+ object.errors << "#{object.class.short_name}[#{@name}] is not valid. It must conform to #{@type.inspect}"
87
+ false
88
+ end
89
+ else
90
+ true
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,69 @@
1
+ require 'quickbooks/types'
2
+ module Quickbooks
3
+ module Properties
4
+ def self.singularize
5
+ Quickbooks::Property
6
+ end
7
+ end
8
+ class Property
9
+ def self.pluralize
10
+ Quickbooks::Properties
11
+ end
12
+ class << self
13
+ attr_accessor :xsd
14
+
15
+ def native
16
+ @native ||= Quickbooks::Types.const_get(xsd.type.name)
17
+ end
18
+
19
+ alias :instantiate :new
20
+ end
21
+
22
+ attr_reader :value
23
+ def value=(value)
24
+ @value = ((value.is_a?(self.class.native) || value.nil?) ? value : self.class.native.new(value))
25
+ end
26
+ alias :__value__ :value
27
+
28
+ def initialize(value=nil)
29
+ raise RuntimeError, "Type class '#{self.class.short_name}' has no native class set. This is a BUG. Please report it!" unless self.class.native.is_a?(Class)
30
+ @value = value.is_a?(self.class.native) ? value : self.class.native.new(value)
31
+ end
32
+
33
+ def eql?(value)
34
+ @value.eql?(value)
35
+ end
36
+ alias :=== :eql?
37
+
38
+ def nil?
39
+ @value.nil?
40
+ end
41
+
42
+ def inspect
43
+ "#{self.class.short_name}[#{@value.class.short_name.gsub(/type$/,'')}]=#{@value.inspect}"
44
+ end
45
+
46
+ def to_s
47
+ @value.to_s
48
+ end
49
+ def to_xml
50
+ '<' + self.class.short_name + '>' + @value.to_xml + '</' + self.class.short_name + '>'
51
+ end
52
+ def to_dirty_xml(include_required=false)
53
+ to_xml
54
+ end
55
+
56
+ def method_missing(method_name, *args, &block)
57
+ if block_given?
58
+ if @value.respond_to?(method_name)
59
+ @value.method(method_name).call(*args) {|*arr| yield *arr }
60
+ else
61
+ args << block
62
+ @value.send(method_name, *args)
63
+ end
64
+ else
65
+ @value.send(method_name, *args)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,251 @@
1
+ class Module
2
+ def short_name
3
+ name.gsub(/.*::/,'')
4
+ end
5
+ end
6
+
7
+ class Array
8
+ def to_hash_via(&block) # Expects the block to receive each element and return a two-element array
9
+ Hash[*(collect {|e| yield e}.flatten)]
10
+ end
11
+
12
+ def group_by_count(int)
13
+ ary = []
14
+ nxt = 0
15
+ until(nxt*4 > length)
16
+ n = []
17
+ int.times do |i|
18
+ break if nxt*4+i >= length
19
+ n << self[nxt*4+i]
20
+ end
21
+ nxt += 1
22
+ ary << n unless n.empty?
23
+ end
24
+ ary
25
+ end
26
+
27
+ def check_all?
28
+ passed = true
29
+ each { |e| passed = false unless yield(e) }
30
+ passed
31
+ end
32
+
33
+ def occurrances_of
34
+ count = 0
35
+ each { |e| count += 1 if yield(e) }
36
+ count
37
+ end
38
+
39
+ # # Gives Array#first the ability to pass a block, and the first item that causes the block to return true is returned
40
+ # def first(count=1)
41
+ # if block_given?
42
+ # choice = self.inject([]) {|a,j| a << j if yield(j); break(a) if a.length == count; a}
43
+ # return count > 1 ? choice : choice[0]
44
+ # else
45
+ # count > 1 ? self[0..(count-1)] : self[0]
46
+ # end
47
+ # end
48
+ end
49
+
50
+ class String
51
+ def countr(regexp)
52
+ i = 0
53
+ gsub(regexp) {|m| i += 1}
54
+ i
55
+ end
56
+
57
+ def xml_escaped
58
+ gsub(/[&<>'"]/) {|match|
59
+ case match
60
+ when '&' then return '&amp;'
61
+ when '<' then return '&lt;'
62
+ when '>' then return '&gt;'
63
+ when "'" then return '&apos;'
64
+ when '"' then return '&quote;'
65
+ end
66
+ }
67
+ end
68
+
69
+ def unescape_xml
70
+ gsub(/&(amp|quot|gt|lt|\#[0-9]+|\#x[0-9A-Fa-f]+);/n) do
71
+ match = $1.dup
72
+ case match
73
+ when 'amp' then '&'
74
+ when 'quot' then '"'
75
+ when 'gt' then '>'
76
+ when 'lt' then '<'
77
+ when /\A#0*(\d+)\z/n then
78
+ if Integer($1) < 256
79
+ Integer($1).chr
80
+ else
81
+ if Integer($1) < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
82
+ [Integer($1)].pack("U")
83
+ else
84
+ "&##{$1};"
85
+ end
86
+ end
87
+ when /\A#x([0-9a-f]+)\z/ni then
88
+ if $1.hex < 256
89
+ $1.hex.chr
90
+ else
91
+ if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)
92
+ [$1.hex].pack("U")
93
+ else
94
+ "&#x#{$1};"
95
+ end
96
+ end
97
+ else
98
+ "&#{match};"
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ class Boolean
105
+ def initialize(value)
106
+ raise ArgumentError, "must be true or false!" unless ['true', 'false'].include?(value.to_s)
107
+ @value = (value.to_s == 'true')
108
+ end
109
+
110
+ def __value__
111
+ @value
112
+ end
113
+
114
+ def ==(other)
115
+ to_s == other.to_s
116
+ end
117
+
118
+ def to_s
119
+ @value.to_s
120
+ end
121
+ alias :inspect :to_s
122
+ end
123
+
124
+ module Kernel
125
+ def todo(task)
126
+ $TODO ||= []
127
+ $TODO << task
128
+ end
129
+ end
130
+
131
+ require 'rexml/light/node'
132
+ require 'rexml/document'
133
+ module Quickbooks
134
+ module Support
135
+ def self.parse_xml(xml)
136
+ stack = []
137
+ parser = REXML::Parsers::BaseParser.new(xml)
138
+ while true
139
+ event = parser.pull
140
+ case event[0]
141
+ when :end_document
142
+ break
143
+ when :end_doctype, :start_doctype
144
+ # do nothing
145
+ when :start_element
146
+ stack.push(event[2].empty? ? QB[event[1]].instantiate : QB[event[1]].instantiate(event[2]))
147
+ when :end_element
148
+ if stack.size > 1
149
+ temp = stack.pop
150
+ stack.last.attributes << temp
151
+ end
152
+ when :text, :cdata
153
+ stack.last.value = event[1].unescape_xml if stack.last.class < Quickbooks::Property
154
+ end
155
+ end
156
+ obj = stack.pop
157
+ obj.send(:clean!)
158
+ obj
159
+ end
160
+
161
+ module Amount
162
+ def self.new(whatever)
163
+ amt = case
164
+ when whatever.is_a?(String)
165
+ # Sanitize the string, taking out things like $.
166
+ whatever.gsub(/[^\d\.+-]/,'').match(/([+-]?\d{1,13}(?:\.\d\d)?)/)[1]
167
+ when whatever.respond_to?(:to_f)
168
+ whatever # cool, it can do to_f
169
+ when whatever.respond_to?(:to_s)
170
+ self.new(whatever.to_s) # to_s will be the second-best opportunity
171
+ when whatever.respond_to?(:to_i)
172
+ whatever.to_i # last resort, use integer
173
+ else
174
+ raise "Invalid value for Amount. Must be up to 13 digits with optional 2-digit decimal place."
175
+ end
176
+ # Format it
177
+ "%.2f" % amt.to_f
178
+ end
179
+ end
180
+ module DateTime
181
+ def self.new(whatever)
182
+ case
183
+ when String
184
+ ::DateTime.parse(whatever)
185
+ when ::DateTime
186
+ whatever
187
+ when whatever.respond_to?(:to_datetime)
188
+ whatever.to_datetime
189
+ when whatever.respond_to?(:to_s)
190
+ ::DateTime.parse(whatever.to_s)
191
+ else
192
+ ::DateTime.new(whatever)
193
+ end
194
+ end
195
+ end
196
+ module Date
197
+ def self.new(whatever)
198
+ case
199
+ when whatever.is_a?(::String)
200
+ ::Date.parse(whatever)
201
+ when whatever.is_a?(::Date)
202
+ whatever
203
+ when whatever.respond_to?(:to_date)
204
+ whatever.to_date
205
+ when whatever.respond_to?(:to_s)
206
+ ::Date.parse(whatever.to_s)
207
+ else
208
+ ::Date.new(whatever)
209
+ end
210
+ end
211
+ end
212
+ module Float
213
+ def self.new(flt)
214
+ flt.to_f
215
+ end
216
+ end
217
+ module Integer
218
+ def self.new(int)
219
+ int.to_i
220
+ end
221
+ end
222
+ module TimeInterval
223
+ # The TIMEINTERVALTYPE type takes the form PTnHnMnS:
224
+ # The characters P and T are always present.
225
+ # • The character H follows the number of hours.
226
+ # • The character M follows the number of minutes.
227
+ # • The character S follows the number of seconds.
228
+ # • n is an integer that represents the number of hours, minutes, or seconds.
229
+ # Examples:
230
+ # PT2H30M0S means: 2 hours, 30 minutes
231
+ # PT2H0M0S means: 2 hours
232
+ # PT0H0M5S means: 5 seconds
233
+ def self.new(whatever)
234
+ case
235
+ when whatever.is_a?(String) && whatever =~ /PT\d\d?H\d\d?M\d\d?S/
236
+ whatever
237
+ when whatever.is_a?(String) && whatever =~ /(\d\d?):(\d\d?)(?:\.(\d\d?))?/
238
+ s, hours, minutes, seconds = *whatever.match(/(\d\d?):(\d\d?)(?:\.(\d\d?))?/)
239
+ "PT#{hours.to_i}H#{minutes.to_i}M#{seconds.to_i}S"
240
+ when whatever.is_a?(Duration)
241
+ hours = whatever.hours.to_i
242
+ minutes = (whatever - hours.hours).minutes.to_i
243
+ seconds = (whatever - hours.hours - minutes.minutes).seconds.to_i
244
+ "PT#{hours}H#{minutes}M#{seconds}S"
245
+ else
246
+ raise ArgumentError, "duration given must be either a String formatted correctly (/PT\d\d?H\d\d?M\d\d?S/, where ) or a Duration object (try whatever english makes sense: 1.hour + 20.minutes, for example.)"
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
@@ -0,0 +1,75 @@
1
+ require 'quickbooks/types'
2
+ module Quickbooks
3
+ class Type
4
+ class << self
5
+ def native(type=nil)
6
+ @native = type if type
7
+ @native
8
+ end
9
+
10
+ alias :instantiate :new
11
+ end
12
+
13
+ attr_reader :value
14
+ def value=(value)
15
+ @value = ((value.is_a?(self.class.native) || value.nil?) ? value : self.class.native.new(value))
16
+ end
17
+ alias :__value__ :value
18
+
19
+ def initialize(value=nil)
20
+ raise RuntimeError, "Type class '#{self.class.short_name}' has no native class set. This is a BUG. Please report it!" unless self.class.native.is_a?(Module)
21
+ self.value = value
22
+ clean!
23
+ end
24
+
25
+ def eql?(value)
26
+ @value.eql?(value)
27
+ end
28
+ alias :=== :eql?
29
+
30
+ def nil?
31
+ @value.nil?
32
+ end
33
+
34
+ def to_s
35
+ @value.to_s
36
+ end
37
+
38
+ def dirty?
39
+ @dirty || @value != @original_value
40
+ end
41
+
42
+ def valid?
43
+ raise "Not Implemented Yet! (Type Validation)"
44
+ end
45
+
46
+ def inspect
47
+ $DEBUG ? super : @value.inspect
48
+ end
49
+
50
+ def to_xml
51
+ @value.to_s.xml_escaped
52
+ end
53
+
54
+ private
55
+
56
+ def clean!
57
+ @dirty = false
58
+ begin
59
+ @original_value = [NilClass, Fixnum].include?(@value.class) ? @value : @value.dup # Fixnum and NilClass can't be dup'd
60
+ rescue TypeError
61
+ @original_value = @value
62
+ end
63
+ end
64
+
65
+ def dirty!
66
+ @dirty = true
67
+ end
68
+
69
+ def method_missing(method_name, *args, &block)
70
+ block_given? ?
71
+ @value.method(method_name).call(*args) {|*arr| yield *arr } :
72
+ @value.method(method_name).call(*args)
73
+ end
74
+ end
75
+ end