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.
- data.tar.gz.sig +0 -0
- data/History.txt +23 -0
- data/License.txt +54 -0
- data/Manifest.txt +73 -0
- data/README.txt +79 -0
- data/Rakefile +17 -78
- data/lib/quickbooks.rb +153 -7
- data/lib/quickbooks/adaptability.rb +67 -0
- data/lib/quickbooks/adapters/http_adapter.rb +94 -0
- data/lib/quickbooks/adapters/https_adapter.rb +57 -0
- data/lib/quickbooks/adapters/ole_adapter.rb +141 -110
- data/lib/quickbooks/adapters/spew_adapter.rb +39 -0
- data/lib/quickbooks/adapters/tcp_adapter.rb +71 -0
- data/lib/quickbooks/adapters/test_adapter.rb +62 -0
- data/lib/quickbooks/element.rb +385 -0
- data/lib/quickbooks/element_collection.rb +105 -0
- data/lib/quickbooks/extlib.rb +8 -0
- data/lib/quickbooks/extlib/assertions.rb +8 -0
- data/lib/quickbooks/extlib/class.rb +98 -0
- data/lib/quickbooks/extlib/days_and_times.rb +10 -0
- data/lib/quickbooks/extlib/days_and_times/duration.rb +362 -0
- data/lib/quickbooks/extlib/days_and_times/numeric.rb +48 -0
- data/lib/quickbooks/extlib/days_and_times/object.rb +19 -0
- data/lib/quickbooks/extlib/days_and_times/time.rb +137 -0
- data/lib/quickbooks/extlib/hash.rb +327 -0
- data/lib/quickbooks/extlib/hook.rb +366 -0
- data/lib/quickbooks/extlib/inflection.rb +436 -0
- data/lib/quickbooks/extlib/logger.rb +202 -0
- data/lib/quickbooks/extlib/object.rb +162 -0
- data/lib/quickbooks/extlib/pathname.rb +15 -0
- data/lib/quickbooks/extlib/rubygems.rb +38 -0
- data/lib/quickbooks/extlib/string.rb +32 -0
- data/lib/quickbooks/extlib/time.rb +41 -0
- data/lib/quickbooks/model.rb +503 -121
- data/lib/quickbooks/option.rb +95 -0
- data/lib/quickbooks/property.rb +69 -0
- data/lib/quickbooks/ruby_ext.rb +251 -0
- data/lib/quickbooks/type.rb +75 -0
- data/lib/quickbooks/types.rb +58 -0
- data/lib/quickbooks/version.rb +10 -0
- data/lib/quickbooks/xsd.rb +243 -0
- data/lib/quickbooks/xsd/attribute.rb +57 -0
- data/lib/quickbooks/xsd/choice.rb +94 -0
- data/lib/quickbooks/xsd/complex_type.rb +77 -0
- data/lib/quickbooks/xsd/element.rb +214 -0
- data/lib/quickbooks/xsd/group.rb +94 -0
- data/lib/quickbooks/xsd/restriction.rb +51 -0
- data/lib/quickbooks/xsd/sequence.rb +85 -0
- data/lib/quickbooks/xsd/simple_type.rb +87 -0
- data/lib/quickbooks/xsd/union.rb +70 -0
- data/lib/quickbooks/xsd/validation.rb +89 -0
- data/lib/quickbooks/xsd/xml_parse.rb +80 -0
- data/quickbooks.gemspec +36 -0
- data/source/qbxml21_demo.xsd +2223 -0
- data/source/qbxmlops_demo.xsd +483 -0
- data/source/qbxmltypes.xsd +160 -0
- data/spec/association_spec.rb +5 -0
- data/spec/element_collection_spec.rb +8 -0
- data/spec/find_spec.rb +30 -0
- data/spec/lib/quickbooks/element_spec.rb +83 -0
- data/spec/lib/quickbooks/elements/sales_order_add_spec.rb +14 -0
- data/spec/lib/quickbooks/elements/vendor_add_spec.rb +78 -0
- data/spec/lib/quickbooks/model_spec.rb +89 -0
- data/spec/lib/quickbooks/models/customer_spec.rb +52 -0
- data/spec/lib/quickbooks/models/invoice_spec.rb +12 -0
- data/spec/lib/quickbooks/models/sales_order_line_spec.rb +0 -0
- data/spec/lib/quickbooks/models/sales_order_spec.rb +145 -0
- data/spec/lib/quickbooks/xsd/choice_spec.rb +18 -0
- data/spec/pending_spec.rb +11 -0
- data/spec/quickbooks_spec.rb +38 -0
- data/spec/repeatable_spec.rb +20 -0
- data/spec/requires_spec.rb +10 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/validation_spec.rb +24 -0
- metadata +133 -285
- metadata.gz.sig +0 -0
- data/LICENSE +0 -16
- data/README +0 -49
- data/doc/classes/Array.html +0 -368
- data/doc/classes/Array.src/M000026.html +0 -18
- data/doc/classes/Array.src/M000027.html +0 -21
- data/doc/classes/Array.src/M000028.html +0 -18
- data/doc/classes/Array.src/M000029.html +0 -19
- data/doc/classes/Array.src/M000030.html +0 -18
- data/doc/classes/Array.src/M000031.html +0 -23
- data/doc/classes/Array.src/M000032.html +0 -18
- data/doc/classes/Array.src/M000033.html +0 -18
- data/doc/classes/Array.src/M000034.html +0 -18
- data/doc/classes/Array.src/M000035.html +0 -19
- data/doc/classes/Array.src/M000036.html +0 -18
- data/doc/classes/Array.src/M000037.html +0 -23
- data/doc/classes/Array.src/M000038.html +0 -18
- data/doc/classes/Array.src/M000039.html +0 -21
- data/doc/classes/Array.src/M000040.html +0 -18
- data/doc/classes/Array.src/M000041.html +0 -18
- data/doc/classes/Class.html +0 -171
- data/doc/classes/Class.src/M000042.html +0 -18
- data/doc/classes/Class.src/M000043.html +0 -18
- data/doc/classes/Hash.html +0 -516
- data/doc/classes/Hash.src/M000001.html +0 -18
- data/doc/classes/Hash.src/M000002.html +0 -21
- data/doc/classes/Hash.src/M000003.html +0 -18
- data/doc/classes/Hash.src/M000004.html +0 -21
- data/doc/classes/Hash.src/M000005.html +0 -18
- data/doc/classes/Hash.src/M000006.html +0 -20
- data/doc/classes/Hash.src/M000007.html +0 -18
- data/doc/classes/Hash.src/M000008.html +0 -22
- data/doc/classes/Hash.src/M000009.html +0 -18
- data/doc/classes/Hash.src/M000010.html +0 -21
- data/doc/classes/Hash.src/M000011.html +0 -24
- data/doc/classes/Hash.src/M000012.html +0 -18
- data/doc/classes/Hash.src/M000013.html +0 -21
- data/doc/classes/Hash.src/M000014.html +0 -18
- data/doc/classes/Hash.src/M000015.html +0 -21
- data/doc/classes/Hash.src/M000016.html +0 -18
- data/doc/classes/Hash.src/M000017.html +0 -21
- data/doc/classes/Hash.src/M000018.html +0 -27
- data/doc/classes/Hash.src/M000019.html +0 -20
- data/doc/classes/Hash.src/M000020.html +0 -18
- data/doc/classes/Hash.src/M000021.html +0 -18
- data/doc/classes/Hash.src/M000022.html +0 -18
- data/doc/classes/Hash.src/M000023.html +0 -18
- data/doc/classes/Hash.src/M000024.html +0 -18
- data/doc/classes/Hash.src/M000025.html +0 -28
- data/doc/classes/Object.html +0 -278
- data/doc/classes/Object.src/M000044.html +0 -24
- data/doc/classes/Object.src/M000045.html +0 -19
- data/doc/classes/Object.src/M000046.html +0 -24
- data/doc/classes/Object.src/M000047.html +0 -18
- data/doc/classes/Object.src/M000048.html +0 -19
- data/doc/classes/Object.src/M000049.html +0 -18
- data/doc/classes/Object.src/M000050.html +0 -18
- data/doc/classes/Object.src/M000051.html +0 -18
- data/doc/classes/Qbxml.html +0 -131
- data/doc/classes/Qbxml/Request.html +0 -224
- data/doc/classes/Qbxml/Request.src/M000132.html +0 -66
- data/doc/classes/Qbxml/Request.src/M000133.html +0 -19
- data/doc/classes/Qbxml/Request.src/M000134.html +0 -83
- data/doc/classes/Qbxml/RequestSet.html +0 -199
- data/doc/classes/Qbxml/RequestSet.src/M000135.html +0 -22
- data/doc/classes/Qbxml/RequestSet.src/M000136.html +0 -26
- data/doc/classes/Qbxml/RequestSet.src/M000137.html +0 -18
- data/doc/classes/Qbxml/RequestSet.src/M000138.html +0 -22
- data/doc/classes/Qbxml/Response.html +0 -302
- data/doc/classes/Qbxml/Response.src/M000123.html +0 -24
- data/doc/classes/Qbxml/Response.src/M000124.html +0 -19
- data/doc/classes/Qbxml/Response.src/M000125.html +0 -55
- data/doc/classes/Qbxml/Response.src/M000126.html +0 -18
- data/doc/classes/Qbxml/Response.src/M000127.html +0 -18
- data/doc/classes/Qbxml/Response.src/M000128.html +0 -18
- data/doc/classes/Qbxml/Response.src/M000129.html +0 -18
- data/doc/classes/Qbxml/Response.src/M000130.html +0 -18
- data/doc/classes/Qbxml/Response.src/M000131.html +0 -63
- data/doc/classes/Qbxml/ResponseSet.html +0 -244
- data/doc/classes/Qbxml/ResponseSet.src/M000116.html +0 -22
- data/doc/classes/Qbxml/ResponseSet.src/M000117.html +0 -26
- data/doc/classes/Qbxml/ResponseSet.src/M000118.html +0 -24
- data/doc/classes/Qbxml/ResponseSet.src/M000119.html +0 -20
- data/doc/classes/Qbxml/ResponseSet.src/M000120.html +0 -27
- data/doc/classes/Qbxml/ResponseSet.src/M000121.html +0 -18
- data/doc/classes/Qbxml/ResponseSet.src/M000122.html +0 -18
- data/doc/classes/Quickbooks.html +0 -196
- data/doc/classes/Quickbooks/Address.html +0 -139
- data/doc/classes/Quickbooks/Address.src/M000115.html +0 -19
- data/doc/classes/Quickbooks/Base.html +0 -567
- data/doc/classes/Quickbooks/Base.src/M000095.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000096.html +0 -20
- data/doc/classes/Quickbooks/Base.src/M000097.html +0 -19
- data/doc/classes/Quickbooks/Base.src/M000098.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000099.html +0 -19
- data/doc/classes/Quickbooks/Base.src/M000100.html +0 -30
- data/doc/classes/Quickbooks/Base.src/M000101.html +0 -22
- data/doc/classes/Quickbooks/Base.src/M000102.html +0 -30
- data/doc/classes/Quickbooks/Base.src/M000103.html +0 -19
- data/doc/classes/Quickbooks/Base.src/M000104.html +0 -19
- data/doc/classes/Quickbooks/Base.src/M000105.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000106.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000107.html +0 -19
- data/doc/classes/Quickbooks/Base.src/M000108.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000109.html +0 -45
- data/doc/classes/Quickbooks/Base.src/M000110.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000111.html +0 -18
- data/doc/classes/Quickbooks/Base.src/M000112.html +0 -20
- data/doc/classes/Quickbooks/BillAddress.html +0 -113
- data/doc/classes/Quickbooks/CreditCardInfo.html +0 -113
- data/doc/classes/Quickbooks/Customer.html +0 -113
- data/doc/classes/Quickbooks/CustomerTypeRef.html +0 -113
- data/doc/classes/Quickbooks/Deleted.html +0 -113
- data/doc/classes/Quickbooks/ItemSalesTaxRef.html +0 -113
- data/doc/classes/Quickbooks/JobTypeRef.html +0 -113
- data/doc/classes/Quickbooks/ListDeleted.html +0 -139
- data/doc/classes/Quickbooks/ListDeleted.src/M000114.html +0 -18
- data/doc/classes/Quickbooks/ListItem.html +0 -170
- data/doc/classes/Quickbooks/ListItem.src/M000093.html +0 -20
- data/doc/classes/Quickbooks/ListItem.src/M000094.html +0 -18
- data/doc/classes/Quickbooks/Model.html +0 -462
- data/doc/classes/Quickbooks/Model.src/M000073.html +0 -24
- data/doc/classes/Quickbooks/Model.src/M000074.html +0 -19
- data/doc/classes/Quickbooks/Model.src/M000075.html +0 -18
- data/doc/classes/Quickbooks/Model.src/M000076.html +0 -18
- data/doc/classes/Quickbooks/Model.src/M000077.html +0 -18
- data/doc/classes/Quickbooks/Model.src/M000078.html +0 -22
- data/doc/classes/Quickbooks/Model.src/M000079.html +0 -32
- data/doc/classes/Quickbooks/Model.src/M000080.html +0 -32
- data/doc/classes/Quickbooks/Model.src/M000081.html +0 -18
- data/doc/classes/Quickbooks/Model.src/M000082.html +0 -18
- data/doc/classes/Quickbooks/Model.src/M000083.html +0 -22
- data/doc/classes/Quickbooks/Model.src/M000084.html +0 -23
- data/doc/classes/Quickbooks/Model.src/M000085.html +0 -18
- data/doc/classes/Quickbooks/Model.src/M000086.html +0 -21
- data/doc/classes/Quickbooks/Model.src/M000087.html +0 -26
- data/doc/classes/Quickbooks/Model.src/M000088.html +0 -26
- data/doc/classes/Quickbooks/Model.src/M000089.html +0 -26
- data/doc/classes/Quickbooks/Model.src/M000090.html +0 -21
- data/doc/classes/Quickbooks/Model.src/M000091.html +0 -23
- data/doc/classes/Quickbooks/OleAdapter.html +0 -129
- data/doc/classes/Quickbooks/OleAdapter/Connection.html +0 -343
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000058.html +0 -18
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000059.html +0 -19
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000060.html +0 -24
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000061.html +0 -18
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000062.html +0 -18
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000063.html +0 -21
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000064.html +0 -24
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000065.html +0 -20
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000066.html +0 -24
- data/doc/classes/Quickbooks/OleAdapter/Connection.src/M000067.html +0 -24
- data/doc/classes/Quickbooks/OleAdapter/Ole.html +0 -209
- data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000068.html +0 -21
- data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000069.html +0 -22
- data/doc/classes/Quickbooks/OleAdapter/Ole.src/M000070.html +0 -18
- data/doc/classes/Quickbooks/ParentRef.html +0 -113
- data/doc/classes/Quickbooks/PreferredPaymentMethodRef.html +0 -113
- data/doc/classes/Quickbooks/PriceLevelRef.html +0 -113
- data/doc/classes/Quickbooks/QbxmlDebugAdapter.html +0 -111
- data/doc/classes/Quickbooks/QbxmlDebugAdapter/Connection.html +0 -139
- data/doc/classes/Quickbooks/QbxmlDebugAdapter/Connection.src/M000057.html +0 -18
- data/doc/classes/Quickbooks/Ref.html +0 -146
- data/doc/classes/Quickbooks/Ref.src/M000113.html +0 -18
- data/doc/classes/Quickbooks/SalesRepRef.html +0 -113
- data/doc/classes/Quickbooks/SalesTaxCodeRef.html +0 -113
- data/doc/classes/Quickbooks/ShipAddress.html +0 -113
- data/doc/classes/Quickbooks/TermsRef.html +0 -113
- data/doc/classes/Quickbooks/Transaction.html +0 -154
- data/doc/classes/Quickbooks/Transaction.src/M000071.html +0 -19
- data/doc/classes/Quickbooks/Transaction.src/M000072.html +0 -18
- data/doc/classes/Quickbooks/TxnDeleted.html +0 -139
- data/doc/classes/Quickbooks/TxnDeleted.src/M000092.html +0 -18
- data/doc/classes/String.html +0 -203
- data/doc/classes/String.src/M000052.html +0 -18
- data/doc/classes/String.src/M000053.html +0 -18
- data/doc/classes/String.src/M000054.html +0 -18
- data/doc/classes/String.src/M000055.html +0 -18
- data/doc/classes/String.src/M000056.html +0 -18
- data/doc/created.rid +0 -1
- data/doc/files/LICENSE.html +0 -129
- data/doc/files/README.html +0 -225
- data/doc/files/lib/qbxml/request_rb.html +0 -110
- data/doc/files/lib/qbxml/response_rb.html +0 -109
- data/doc/files/lib/qbxml/support_rb.html +0 -101
- data/doc/files/lib/qbxml_rb.html +0 -122
- data/doc/files/lib/quickbooks/adapters/ole_adapter_rb.html +0 -108
- data/doc/files/lib/quickbooks/adapters/qbxml_debug_adapter_rb.html +0 -108
- data/doc/files/lib/quickbooks/base_rb.html +0 -327
- data/doc/files/lib/quickbooks/model_rb.html +0 -108
- data/doc/files/lib/quickbooks/models/common/address_rb.html +0 -101
- data/doc/files/lib/quickbooks/models/common/all_refs_rb.html +0 -101
- data/doc/files/lib/quickbooks/models/customer/credit_card_info_rb.html +0 -101
- data/doc/files/lib/quickbooks/models/customer_rb.html +0 -110
- data/doc/files/lib/quickbooks/models/deleted_rb.html +0 -101
- data/doc/files/lib/quickbooks/models/list_item_rb.html +0 -101
- data/doc/files/lib/quickbooks/models/transaction_rb.html +0 -101
- data/doc/files/lib/quickbooks/ruby_magic_rb.html +0 -120
- data/doc/files/lib/quickbooks_rb.html +0 -125
- data/doc/fr_class_index.html +0 -64
- data/doc/fr_file_index.html +0 -45
- data/doc/fr_method_index.html +0 -164
- data/doc/index.html +0 -24
- data/doc/rdoc-style.css +0 -208
- data/lib/qbxml.rb +0 -3
- data/lib/qbxml/request.rb +0 -207
- data/lib/qbxml/response.rb +0 -197
- data/lib/qbxml/support.rb +0 -130
- data/lib/quickbooks/adapters/qbxml_debug_adapter.rb +0 -10
- data/lib/quickbooks/base.rb +0 -277
- data/lib/quickbooks/models/common/address.rb +0 -14
- data/lib/quickbooks/models/common/all_refs.rb +0 -37
- data/lib/quickbooks/models/customer.rb +0 -70
- data/lib/quickbooks/models/customer/credit_card_info.rb +0 -5
- data/lib/quickbooks/models/deleted.rb +0 -22
- data/lib/quickbooks/models/list_item.rb +0 -41
- data/lib/quickbooks/models/transaction.rb +0 -49
- 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 '&'
|
|
61
|
+
when '<' then return '<'
|
|
62
|
+
when '>' then return '>'
|
|
63
|
+
when "'" then return '''
|
|
64
|
+
when '"' then return '"e;'
|
|
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
|