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,58 @@
|
|
|
1
|
+
require 'quickbooks/type'
|
|
2
|
+
module Quickbooks
|
|
3
|
+
module Types
|
|
4
|
+
class AMTTYPE < Type
|
|
5
|
+
native Quickbooks::Support::Amount
|
|
6
|
+
end
|
|
7
|
+
class BOOLTYPE < Type
|
|
8
|
+
native Boolean
|
|
9
|
+
end
|
|
10
|
+
class DATETIMETYPE < Type
|
|
11
|
+
native Quickbooks::Support::DateTime
|
|
12
|
+
end
|
|
13
|
+
class DATETYPE < Type
|
|
14
|
+
require 'date'
|
|
15
|
+
native Quickbooks::Support::Date
|
|
16
|
+
end
|
|
17
|
+
class ENUMTYPE < Type
|
|
18
|
+
native String
|
|
19
|
+
# Need to create the Enum functionality. The dtd's don't specify the allowed values for any of the ENUMTYPEs.
|
|
20
|
+
# For example, the JobStatus property holds one of the following:
|
|
21
|
+
# Awarded, Closed, InProgress, None [DEFAULT], NotAwarded, Pending
|
|
22
|
+
# But there is yet no way to specify allowed values or to validate them.
|
|
23
|
+
class << self
|
|
24
|
+
def enum(in_klass,*args)
|
|
25
|
+
@enum ||= {}
|
|
26
|
+
@enum[in_klass] = args
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
class FLOATTYPE < Type
|
|
31
|
+
native Quickbooks::Support::Float
|
|
32
|
+
end
|
|
33
|
+
class GUIDTYPE < Type
|
|
34
|
+
native String
|
|
35
|
+
end
|
|
36
|
+
class IDTYPE < Type
|
|
37
|
+
native String
|
|
38
|
+
end
|
|
39
|
+
class INTTYPE < Type
|
|
40
|
+
native Quickbooks::Support::Integer
|
|
41
|
+
end
|
|
42
|
+
class PERCENTTYPE < Type
|
|
43
|
+
native String
|
|
44
|
+
end
|
|
45
|
+
class PRICETYPE < Type
|
|
46
|
+
native String
|
|
47
|
+
end
|
|
48
|
+
class QUANTYPE < Type
|
|
49
|
+
native Quickbooks::Support::Float
|
|
50
|
+
end
|
|
51
|
+
class STRTYPE < Type
|
|
52
|
+
native String
|
|
53
|
+
end
|
|
54
|
+
class TIMEINTERVALTYPE < Type
|
|
55
|
+
native Quickbooks::Support::TimeInterval
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
class Class
|
|
2
|
+
def cascading_attr_reader(*names)
|
|
3
|
+
names.each do |name|
|
|
4
|
+
class_eval "def #{name}; @#{name} || (parent ? parent.#{name} : nil); end"
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def cascading_attr_accessor(*names)
|
|
9
|
+
names.each do |name|
|
|
10
|
+
attr_writer name
|
|
11
|
+
class_eval "def #{name}; @#{name} || (parent ? parent.#{name} : nil); end"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
req_base = File.dirname(__FILE__)
|
|
17
|
+
require req_base + '/xsd/xml_parse'
|
|
18
|
+
require req_base + '/xsd/validation'
|
|
19
|
+
require req_base + '/xsd/element'
|
|
20
|
+
require req_base + '/xsd/group'
|
|
21
|
+
require req_base + '/xsd/sequence'
|
|
22
|
+
require req_base + '/xsd/simple_type'
|
|
23
|
+
require req_base + '/xsd/complex_type'
|
|
24
|
+
require req_base + '/xsd/restriction'
|
|
25
|
+
require req_base + '/xsd/choice'
|
|
26
|
+
require req_base + '/xsd/union'
|
|
27
|
+
require req_base + '/xsd/attribute'
|
|
28
|
+
|
|
29
|
+
module Quickbooks
|
|
30
|
+
class XSD
|
|
31
|
+
def inspect
|
|
32
|
+
properties_size = properties.size
|
|
33
|
+
sprintf("#<%s:0x%x %s models, %s elements, %s properties, %s types>", self.class.name, __id__, models.size, elements.size - properties_size, properties_size, types.size)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def source_paths
|
|
37
|
+
@source_paths ||= []
|
|
38
|
+
end
|
|
39
|
+
def source_path
|
|
40
|
+
source_paths.last
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def elements
|
|
44
|
+
@elements ||= {}
|
|
45
|
+
end
|
|
46
|
+
def groups
|
|
47
|
+
@groups ||= {}
|
|
48
|
+
end
|
|
49
|
+
def types
|
|
50
|
+
@types ||= {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def properties
|
|
54
|
+
Hash[*elements.select {|k,e| e.is_property?}.flatten]
|
|
55
|
+
end
|
|
56
|
+
def models
|
|
57
|
+
Hash[*elements.select {|k,e| e.is_model?}.flatten]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Get any name that is saved in elements.
|
|
61
|
+
def [](key)
|
|
62
|
+
elements[key]
|
|
63
|
+
end
|
|
64
|
+
def include?(key)
|
|
65
|
+
elements.include?(key)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.parse_file(file, path=nil)
|
|
69
|
+
Quickbooks::XSD.new.parse_file(file, path)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def parse_file(file, path=nil)
|
|
73
|
+
file = (path || source_path) + '/' + file unless path.nil? && source_path.nil?
|
|
74
|
+
|
|
75
|
+
if File.exists?(file)
|
|
76
|
+
file = File.expand_path(file)
|
|
77
|
+
source_paths << File.dirname(file)
|
|
78
|
+
# puts "Parsing #{file}..."
|
|
79
|
+
xsd = parse(File.read(file))
|
|
80
|
+
source_paths.pop
|
|
81
|
+
xsd
|
|
82
|
+
else
|
|
83
|
+
raise "XSD source file #{file} does not exist!"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def parse(source)
|
|
88
|
+
element_stack = []
|
|
89
|
+
waiting_types = Hash.new {|h,k| h[k] = []}
|
|
90
|
+
parser = REXML::Parsers::BaseParser.new(source)
|
|
91
|
+
status = {}
|
|
92
|
+
loop do
|
|
93
|
+
event = parser.pull
|
|
94
|
+
case event[0]
|
|
95
|
+
when :end_document
|
|
96
|
+
break
|
|
97
|
+
when :end_doctype, :start_doctype
|
|
98
|
+
# do nothing
|
|
99
|
+
when :start_element
|
|
100
|
+
# Create a node
|
|
101
|
+
tag_name, attributes = event[1], event[2]
|
|
102
|
+
case tag_name
|
|
103
|
+
when 'xsd:schema'
|
|
104
|
+
# Just the schema element at the top.
|
|
105
|
+
|
|
106
|
+
when 'xsd:include' # Parse this file at this point before continuing.
|
|
107
|
+
parse_file(attributes['schemaLocation'], source_path)
|
|
108
|
+
|
|
109
|
+
when 'xsd:element' # an element. If inside another element any number of levels deep, it's not a declaration, just an inclusion.
|
|
110
|
+
if type_name = attributes.delete('type')
|
|
111
|
+
type = types[type_name]
|
|
112
|
+
attributes.merge!('type' => type)
|
|
113
|
+
end
|
|
114
|
+
element = if element_stack.empty?
|
|
115
|
+
(elements[attributes['name']] ||= Element.new).merge!(attributes)
|
|
116
|
+
elsif attributes.has_key?('ref')
|
|
117
|
+
(elements[attributes['ref']] ||= Element.new).merge(attributes)
|
|
118
|
+
elsif elements.has_key?(attributes['name'])
|
|
119
|
+
elements[attributes['name']].merge(attributes)
|
|
120
|
+
elsif attributes.has_key?('name') && attributes.has_key?('type')
|
|
121
|
+
elements[attributes['name']] ||= Element.new(attributes)
|
|
122
|
+
else
|
|
123
|
+
Element.new(attributes)
|
|
124
|
+
end
|
|
125
|
+
waiting_types[type_name] << element if type_name && type.nil? # When the type is created it will retroactively set the type to this element.
|
|
126
|
+
element_stack.last << element unless element_stack.empty?
|
|
127
|
+
element_stack << element
|
|
128
|
+
|
|
129
|
+
when 'xsd:simpleType' # simpleType means its parent is a property and this defines the possible value
|
|
130
|
+
# If it's being declared on the top level, create a new one
|
|
131
|
+
type = (types[attributes['name']] || SimpleType.new).merge(attributes)
|
|
132
|
+
if element_stack.empty?
|
|
133
|
+
types[type.name] = type
|
|
134
|
+
else
|
|
135
|
+
element_stack.last << type
|
|
136
|
+
end
|
|
137
|
+
element_stack << type
|
|
138
|
+
waiting_types.delete(type.name).each {|e| e.type = type} if type.name && waiting_types.has_key?(type.name)
|
|
139
|
+
|
|
140
|
+
when 'xsd:complexType' # defines a complex requirement, usually a sequence
|
|
141
|
+
# If it's being declared on the top level, create a new one
|
|
142
|
+
type = (types[attributes['name']] || ComplexType.new).merge(attributes)
|
|
143
|
+
if element_stack.empty?
|
|
144
|
+
types[type.name] = type
|
|
145
|
+
else
|
|
146
|
+
element_stack.last << type
|
|
147
|
+
end
|
|
148
|
+
element_stack << type
|
|
149
|
+
waiting_types.delete(type.name).each {|e| e.type = type} if type.name && waiting_types.has_key?(type.name)
|
|
150
|
+
|
|
151
|
+
when 'xsd:restriction' # restriction defines a restriction on the possible value of an element
|
|
152
|
+
element_stack.last.restriction = Restriction.new(attributes)
|
|
153
|
+
element_stack.last.type = types[attributes['base']] # Sets the base type onto the parent SimpleType
|
|
154
|
+
# TODO: currently we don't step into these restrictions, we're referencing them more explicitly (see xsd:enumeration below)
|
|
155
|
+
|
|
156
|
+
when 'xsd:enumeration' # enumerates the values for an ENUM property
|
|
157
|
+
element_stack.last.restriction.enum_values! << attributes.delete('value')
|
|
158
|
+
puts "More attributes for Enumeration: #{attributes.inspect}" unless attributes.empty?
|
|
159
|
+
|
|
160
|
+
when 'xsd:group' # defines a group of elements used together
|
|
161
|
+
group = if element_stack.empty?
|
|
162
|
+
# being declared by name. Save the new attributes into it for sure.
|
|
163
|
+
(groups[attributes['name']] ||= Group.new).merge!(attributes)
|
|
164
|
+
elsif attributes.has_key?('ref')
|
|
165
|
+
# We are referencing a common element, which may or may not already be declared.
|
|
166
|
+
groups[attributes['ref']] ||= Group.new
|
|
167
|
+
else
|
|
168
|
+
# We're not declaring nor are we referencing a declared element.
|
|
169
|
+
Group.new
|
|
170
|
+
end.merge(attributes)
|
|
171
|
+
element_stack.last << group unless element_stack.empty?
|
|
172
|
+
element_stack << group
|
|
173
|
+
|
|
174
|
+
when 'xsd:sequence' # defines a sequence of elements/element-groups
|
|
175
|
+
sequence = Sequence.new(attributes)
|
|
176
|
+
element_stack.last << sequence
|
|
177
|
+
element_stack << sequence
|
|
178
|
+
|
|
179
|
+
when 'xsd:choice' # choice means include any one of the enclosed elements/element-groups
|
|
180
|
+
choice = Choice.new(attributes)
|
|
181
|
+
element_stack.last << choice
|
|
182
|
+
element_stack << choice
|
|
183
|
+
puts "More attributes for Choice: #{attributes.inspect}" unless attributes.empty?
|
|
184
|
+
|
|
185
|
+
when 'xsd:union'
|
|
186
|
+
union = Union.new(attributes)
|
|
187
|
+
element_stack.last << union
|
|
188
|
+
element_stack << union
|
|
189
|
+
puts "More attributes for Union: #{attributes.inspect}" unless attributes.empty?
|
|
190
|
+
|
|
191
|
+
when 'xsd:attribute' # an attribute of the parent element
|
|
192
|
+
if type = attributes.delete('type')
|
|
193
|
+
type = types[type] # assuming that all types are declared before they're referenced.
|
|
194
|
+
attributes.merge!('type' => type)
|
|
195
|
+
end
|
|
196
|
+
attribute = Attribute.new(attributes)
|
|
197
|
+
element_stack.last << attribute
|
|
198
|
+
element_stack << attribute
|
|
199
|
+
|
|
200
|
+
when 'xsd:maxLength' # a restriction of a STRTYPE property
|
|
201
|
+
element_stack.last.restriction.maxLength = attributes.delete('value')
|
|
202
|
+
puts "More attributes for maxLength: #{attributes.inspect}" unless attributes.empty?
|
|
203
|
+
|
|
204
|
+
when 'xsd:pattern' # a restriction of a STRTYPE property
|
|
205
|
+
element_stack.last.restriction.pattern = attributes.delete('value')
|
|
206
|
+
puts "More attributes for pattern: #{attributes.inspect}" unless attributes.empty?
|
|
207
|
+
|
|
208
|
+
when 'xsd:maxInclusive'
|
|
209
|
+
when 'xsd:minInclusive'
|
|
210
|
+
when 'xsd:simpleContent'
|
|
211
|
+
when 'xsd:extension'
|
|
212
|
+
else
|
|
213
|
+
warn "!! Other element: #{tag_name} (#{attributes.inspect})"
|
|
214
|
+
end
|
|
215
|
+
when :end_element
|
|
216
|
+
name = event[1]
|
|
217
|
+
case name
|
|
218
|
+
when 'xsd:element'
|
|
219
|
+
element_stack.pop
|
|
220
|
+
when 'xsd:simpleType'
|
|
221
|
+
element_stack.pop
|
|
222
|
+
when 'xsd:group'
|
|
223
|
+
element_stack.pop
|
|
224
|
+
when 'xsd:union'
|
|
225
|
+
element_stack.pop
|
|
226
|
+
when 'xsd:choice'
|
|
227
|
+
element_stack.pop
|
|
228
|
+
when 'xsd:sequence'
|
|
229
|
+
element_stack.pop
|
|
230
|
+
when 'xsd:complexType'
|
|
231
|
+
element_stack.pop
|
|
232
|
+
when 'xsd:attribute'
|
|
233
|
+
element_stack.pop
|
|
234
|
+
end
|
|
235
|
+
when :text, :cdata
|
|
236
|
+
puts "!! Text Data: #{event[1]}" if event[1].strip.length > 0
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
self
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Quickbooks
|
|
2
|
+
class XSD
|
|
3
|
+
class Attribute
|
|
4
|
+
attr_reader :name, :use, :default
|
|
5
|
+
attr_accessor :type
|
|
6
|
+
|
|
7
|
+
def initialize(attributes)
|
|
8
|
+
@name = attributes.delete('name')
|
|
9
|
+
@type = attributes.delete('type')
|
|
10
|
+
@use = attributes.delete('use')
|
|
11
|
+
@default = attributes.delete('default')
|
|
12
|
+
warn "!! Unhandled Attribute attributes: #{attributes.keys.join(', ')}" if !attributes.empty?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def items
|
|
16
|
+
@items ||= []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def <<(something)
|
|
20
|
+
case something
|
|
21
|
+
when SimpleType
|
|
22
|
+
self.type = something
|
|
23
|
+
else
|
|
24
|
+
items << something
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def validate(object,required=true)
|
|
29
|
+
return Valean.perfect!(name, required) if object.is_a?(Quickbooks::Model)
|
|
30
|
+
# Validate the object's contents
|
|
31
|
+
puts "#{$DEBUG<<"\t"}Validating #{required ? 'REQUIRED' : 'OPTIONAL'} Attribute #{name}" if $DEBUG
|
|
32
|
+
# A) am I required?
|
|
33
|
+
# B) do I exist?
|
|
34
|
+
# TODO: Also validate by @type
|
|
35
|
+
r = Valean.new(name, required, :exists => !object[name].nil?)
|
|
36
|
+
$DEBUG.chop! if $DEBUG
|
|
37
|
+
puts "#{$DEBUG}\t- #{r}" if $DEBUG
|
|
38
|
+
r
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def inspect
|
|
42
|
+
"<Attribute: '#{name}' #{use if use} #{type.inspect} #{"default="+default.inspect if default}>".gsub(/ +/,' ').gsub(/ >/,'>')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Reports whether the named Quickbooks::XSD::Element or other xsd object is required within its container.
|
|
46
|
+
def required?(key_or_xsd=nil)
|
|
47
|
+
@use == 'required'
|
|
48
|
+
end
|
|
49
|
+
def include?(key_or_xsd)
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
def children
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Quickbooks
|
|
2
|
+
class XSD
|
|
3
|
+
class Choice
|
|
4
|
+
attr_accessor :sequence
|
|
5
|
+
|
|
6
|
+
def initialize(attributes)
|
|
7
|
+
@minOccurs = (attributes.delete('minOccurs') || 1).to_i
|
|
8
|
+
@maxOccurs = attributes.delete('maxOccurs')
|
|
9
|
+
@items = attributes.delete(:items)
|
|
10
|
+
puts "More attributes for Choice: #{attributes.inspect}" unless attributes.empty?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def name
|
|
14
|
+
"either of (#{children.collect {|e| e.name}.join(', ')})"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def items
|
|
18
|
+
@items ||= []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def <<(something)
|
|
22
|
+
self.items << something
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def inspect
|
|
26
|
+
sprintf("\n%s", items.map{|i|i.inspect.gsub(/\n/,"\n ")}.join("\n OR"))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def clone
|
|
30
|
+
self.class.new('minOccurs' => @minOccurs, 'maxOccurs' => @maxOccurs, :items => items.map {|i| i.clone})
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# true if present and valid, or optional and missing
|
|
34
|
+
# false if required and either missing or invalid content
|
|
35
|
+
# :invalid if optional and invalid content
|
|
36
|
+
def validate(object,required=true)
|
|
37
|
+
# Validate the object's contents
|
|
38
|
+
puts "#{$DEBUG<<"\t"}Validating CONFORMS TO #Choice (#{required ? 'REQUIRED' : 'OPTIONAL'})" if $DEBUG
|
|
39
|
+
# 1) Is it required?
|
|
40
|
+
r = Valean.new(nil,required)
|
|
41
|
+
# 2) Do any of the choices exist? (if not, choice is missing)
|
|
42
|
+
# TODO: PROBLEM WITH THIS LINE -- DOESN'T ALWAYS FIND EXISTENCE!!!
|
|
43
|
+
existing = items.select {|i| i.exists_in?(object)}
|
|
44
|
+
r.exists! if existing.length > 0
|
|
45
|
+
# 3) Does ONLY ONE of the choices exist? (if not, choice itself is invalid)
|
|
46
|
+
r.invalid!("Must only include 1 of #{children.collect {|e| e.name}.inspect}") if existing.length > 1
|
|
47
|
+
# 4) Is the existing choice valid? (if not, the item is invalid)
|
|
48
|
+
r << existing[0].validate(object) if !existing.empty? && r.perfect?
|
|
49
|
+
$DEBUG.chop! if $DEBUG
|
|
50
|
+
puts "#{$DEBUG}\t- #{r}" if $DEBUG
|
|
51
|
+
r
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def exists_in?(other)
|
|
55
|
+
items.any? {|i| i.exists_in?(other)}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def find(key)
|
|
59
|
+
children.select {|i| i.name == key}[0]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def include?(key_or_xsd)
|
|
63
|
+
key_or_xsd.is_a?(String) ?
|
|
64
|
+
children.collect {|e| e.name}.include?(key_or_xsd) :
|
|
65
|
+
(key_or_xsd == self || items.any? {|i| i.include?(key_or_xsd)})
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def index(key)
|
|
69
|
+
children.collect {|e| e.name}.index(key.to_s)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Reports whether the named Quickbooks::XSD::Element or other xsd object is allowed more than once in its parent.
|
|
73
|
+
def repeatable?(key=nil)
|
|
74
|
+
if key
|
|
75
|
+
# puts "Checking repeatable: #{items.inspect}"
|
|
76
|
+
repeatable? || items.any? {|i| i.include?(key) && i.repeatable?(key)}
|
|
77
|
+
else
|
|
78
|
+
@maxOccurs == 'unbounded'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Reports whether the named Quickbooks::XSD::Element or other xsd object is required within its container.
|
|
83
|
+
def required?(key_or_xsd=nil)
|
|
84
|
+
(key_or_xsd && @minOccurs > 0) || false
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def children
|
|
88
|
+
children = []
|
|
89
|
+
items.map {|i| i.is_a?(Quickbooks::XSD::Element) ? children << i : children.concat(i.children)}
|
|
90
|
+
children
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|