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,105 @@
|
|
|
1
|
+
class ElementCollection
|
|
2
|
+
include Enumerable
|
|
3
|
+
def each
|
|
4
|
+
items.each {|e| yield e}
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
attr_reader :type
|
|
8
|
+
def initialize(parent, type, items=[])
|
|
9
|
+
@parent = parent
|
|
10
|
+
@type = QB[type.to_s]
|
|
11
|
+
(items.is_a?(Enumerable) ? items : [items]).each { |item| add_item(item) }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Access items by index.
|
|
15
|
+
def [](index)
|
|
16
|
+
items[index]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Adds an item to the collection. The item type must be the same as the registered type for this Collection.
|
|
20
|
+
def build(item={})
|
|
21
|
+
raise RuntimeError, "cannot introduce an existing #{@type.to_s} to a new #{self.class.short_name}!" if item.is_a?(Quickbooks::Model) && !item.new_record? && @parent.new_record?
|
|
22
|
+
item = add_item(item)
|
|
23
|
+
item.instance_variable_set(:@collection_index, items.length-1)
|
|
24
|
+
return item
|
|
25
|
+
end
|
|
26
|
+
alias :<< :build
|
|
27
|
+
|
|
28
|
+
# Returns the number of items in the collection
|
|
29
|
+
def length
|
|
30
|
+
items.length
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def empty? #:nodoc:
|
|
34
|
+
items.empty?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def valid?
|
|
38
|
+
errors.clear
|
|
39
|
+
r = items.inject(Valean.new) {|r,e| r << e.validate; r}
|
|
40
|
+
errors.concat(r.errors) if !r.errors.empty?
|
|
41
|
+
r.perfect?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def errors
|
|
45
|
+
@errors ||= []
|
|
46
|
+
end
|
|
47
|
+
def add_error(msg) #:nodoc:
|
|
48
|
+
errors << [nil, msg]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def dirty? #:nodoc:
|
|
52
|
+
@dirty ||= false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def inspect #:nodoc:
|
|
56
|
+
"[Collection of #{@type.short_name}: #{items.join(', ')}]"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# TODO: Has a problem when an element is a new_record and a child isn't, or vice-versa.
|
|
60
|
+
def to_element #:nodoc:
|
|
61
|
+
element_klass = @type < Quickbooks::Model ? (@type.short_name + (@parent.new_record? ? 'Add' : 'Mod')) : @type.short_name
|
|
62
|
+
puts "Converting to #{element_klass}"
|
|
63
|
+
elements = ElementCollection.new(@parent, element_klass)
|
|
64
|
+
items.each {|e| elements << (@type < Quickbooks::Model ? e.to_element : e)}
|
|
65
|
+
return elements
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_model #:nodoc:
|
|
69
|
+
# Strips off Add, Mod, or Ret to turn whatever it is into a Model object
|
|
70
|
+
models = ElementCollection.new(@parent, @type.short_name.gsub(/(Add|Mod|Ret)$/,''))
|
|
71
|
+
items.each {|e| models << e.to_model}
|
|
72
|
+
return models
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns this collection but as a regular Array.
|
|
76
|
+
def to_a
|
|
77
|
+
items.dup
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def save_associations #:nodoc:
|
|
81
|
+
each { |el| el.save_associations if el.respond_to?(:save_associations) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def items
|
|
87
|
+
@items ||= []
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def add_item(item)
|
|
91
|
+
item = @type.new(item) unless item.is_a?(@type)
|
|
92
|
+
item.send(:dirty!) if dirty?
|
|
93
|
+
items << item
|
|
94
|
+
return item
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def clean!
|
|
98
|
+
@dirty = false
|
|
99
|
+
items.each {|e| e.send(:clean!)}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def dirty!
|
|
103
|
+
@dirty = true
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
require 'quickbooks/extlib/class'
|
|
2
|
+
require 'quickbooks/extlib/object'
|
|
3
|
+
require 'quickbooks/extlib/string'
|
|
4
|
+
require 'quickbooks/extlib/hash'
|
|
5
|
+
require 'quickbooks/extlib/time'
|
|
6
|
+
require 'quickbooks/extlib/assertions'
|
|
7
|
+
require 'quickbooks/extlib/inflection'
|
|
8
|
+
require 'quickbooks/extlib/days_and_times'
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module Extlib
|
|
2
|
+
module Assertions
|
|
3
|
+
def assert_kind_of(name, value, *klasses)
|
|
4
|
+
klasses.each { |k| return if value.kind_of?(k) }
|
|
5
|
+
raise ArgumentError, "+#{name}+ should be #{klasses.map { |k| k.name } * ' or '}, but was #{value.class.name}", caller(2)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
# a copy of this software and associated documentation files (the
|
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
# the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be
|
|
12
|
+
# included in all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
# Allows attributes to be shared within an inheritance hierarchy, but where
|
|
23
|
+
# each descendant gets a copy of their parents' attributes, instead of just a
|
|
24
|
+
# pointer to the same. This means that the child can add elements to, for
|
|
25
|
+
# example, an array without those additions being shared with either their
|
|
26
|
+
# parent, siblings, or children, which is unlike the regular class-level
|
|
27
|
+
# attributes that are shared across the entire hierarchy.
|
|
28
|
+
class Class
|
|
29
|
+
# Defines class-level and instance-level attribute reader.
|
|
30
|
+
#
|
|
31
|
+
# @param *syms<Array> Array of attributes to define reader for.
|
|
32
|
+
# @return <Array[#to_s]> List of attributes that were made into cattr_readers
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
#
|
|
36
|
+
# @todo Is this inconsistent in that it does not allow you to prevent
|
|
37
|
+
# an instance_reader via :instance_reader => false
|
|
38
|
+
def cattr_reader(*syms)
|
|
39
|
+
syms.flatten.each do |sym|
|
|
40
|
+
next if sym.is_a?(Hash)
|
|
41
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
|
42
|
+
unless defined? @@#{sym}
|
|
43
|
+
@@#{sym} = nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.#{sym}
|
|
47
|
+
@@#{sym}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def #{sym}
|
|
51
|
+
@@#{sym}
|
|
52
|
+
end
|
|
53
|
+
RUBY
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Defines class-level (and optionally instance-level) attribute writer.
|
|
58
|
+
#
|
|
59
|
+
# @param <Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define writer for.
|
|
60
|
+
# @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
|
|
61
|
+
# @return <Array[#to_s]> List of attributes that were made into cattr_writers
|
|
62
|
+
#
|
|
63
|
+
# @api public
|
|
64
|
+
def cattr_writer(*syms)
|
|
65
|
+
options = syms.last.is_a?(Hash) ? syms.pop : {}
|
|
66
|
+
syms.flatten.each do |sym|
|
|
67
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
|
68
|
+
unless defined? @@#{sym}
|
|
69
|
+
@@#{sym} = nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.#{sym}=(obj)
|
|
73
|
+
@@#{sym} = obj
|
|
74
|
+
end
|
|
75
|
+
RUBY
|
|
76
|
+
|
|
77
|
+
unless options[:instance_writer] == false
|
|
78
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
|
79
|
+
def #{sym}=(obj)
|
|
80
|
+
@@#{sym} = obj
|
|
81
|
+
end
|
|
82
|
+
RUBY
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Defines class-level (and optionally instance-level) attribute accessor.
|
|
88
|
+
#
|
|
89
|
+
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define accessor for.
|
|
90
|
+
# @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
|
|
91
|
+
# @return <Array[#to_s]> List of attributes that were made into accessors
|
|
92
|
+
#
|
|
93
|
+
# @api public
|
|
94
|
+
def cattr_accessor(*syms)
|
|
95
|
+
cattr_reader(*syms)
|
|
96
|
+
cattr_writer(*syms)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module DaysAndTimes
|
|
2
|
+
def self.VERSION
|
|
3
|
+
'1.0.0'
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require File.dirname(__FILE__)+'/days_and_times/duration'
|
|
8
|
+
require File.dirname(__FILE__)+'/days_and_times/numeric'
|
|
9
|
+
require File.dirname(__FILE__)+'/days_and_times/time'
|
|
10
|
+
require File.dirname(__FILE__)+'/days_and_times/object'
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
require 'time'
|
|
2
|
+
class Duration
|
|
3
|
+
# Length is the length of the time span, in seconds
|
|
4
|
+
# Unit is a length of time (in seconds) to use in collection methods
|
|
5
|
+
# StartTime is an optional attribute that can 'anchor' a duration
|
|
6
|
+
# to a specific real time.
|
|
7
|
+
attr_accessor :length, :unit, :start_time
|
|
8
|
+
def initialize(count=0,unit=1,start_time=nil,auto_klass={})
|
|
9
|
+
if unit.is_a?(Time) || unit.is_a?(DateTime)
|
|
10
|
+
start_time = unit
|
|
11
|
+
unit = 1
|
|
12
|
+
end
|
|
13
|
+
options = {:count => count || 0, :unit => unit || 1, :start_time => start_time}.merge(count.is_a?(Hash) ? count : {})
|
|
14
|
+
|
|
15
|
+
@unit = options[:unit]
|
|
16
|
+
@length = (@unit * options[:count].to_f).round
|
|
17
|
+
@start_time = options[:start_time]
|
|
18
|
+
end
|
|
19
|
+
def self.new(*args)
|
|
20
|
+
a = super
|
|
21
|
+
if self.name == 'Duration' && (args.last.is_a?(Hash) ? args.last[:auto_class] == true : true)
|
|
22
|
+
a.send(:auto_class)
|
|
23
|
+
else
|
|
24
|
+
a
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
def self.length
|
|
28
|
+
1
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# * * * * * * * * * * * * * * * *
|
|
32
|
+
# A Duration is a LENGTH of Time
|
|
33
|
+
# -This is measured in seconds,
|
|
34
|
+
# but set in terms of the unit
|
|
35
|
+
# currently being used.
|
|
36
|
+
def length=(value)
|
|
37
|
+
if value.respond_to?(:to_f)
|
|
38
|
+
@length = (self.unit * value.to_f).round
|
|
39
|
+
else
|
|
40
|
+
raise TypeError, "Can't set a Duration's length to a #{value.class.name} object."
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
def length
|
|
44
|
+
length = @length.to_f / self.unit
|
|
45
|
+
length.to_i == length ? length.to_i : length
|
|
46
|
+
end
|
|
47
|
+
def abs_length=(value)
|
|
48
|
+
if value.respond_to?(:to_i)
|
|
49
|
+
@length = value.to_i
|
|
50
|
+
else
|
|
51
|
+
raise TypeError, "Can't set a Duration's length to a #{value.class.name} object."
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
def abs_length
|
|
55
|
+
@length
|
|
56
|
+
end
|
|
57
|
+
def to_i
|
|
58
|
+
self.abs_length.to_i
|
|
59
|
+
end
|
|
60
|
+
def to_f
|
|
61
|
+
self.abs_length.to_f
|
|
62
|
+
end
|
|
63
|
+
def to_s
|
|
64
|
+
"#{self.length} #{self.class.name}"
|
|
65
|
+
end
|
|
66
|
+
def coerce(*args)
|
|
67
|
+
to_f.coerce(*args)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def ===(other)
|
|
71
|
+
self.to_f == other.to_f
|
|
72
|
+
end
|
|
73
|
+
def inspect
|
|
74
|
+
"#<#{self.class.name}:#{self.object_id} (length=#{self.length.inspect}) #{self.instance_variables.reject {|d| d=='@length' || self.instance_variable_get(d).nil?}.collect {|iv| "#{iv}=#{self.instance_variable_get(iv).inspect}"}.join(' ')}>"
|
|
75
|
+
end
|
|
76
|
+
# * * * * * * * * * * * * * * * *
|
|
77
|
+
|
|
78
|
+
# * * * * * * * * * * * * * * * * * * * * *
|
|
79
|
+
# A Duration's calculations utilize a UNIT
|
|
80
|
+
# -This is stored as the number of
|
|
81
|
+
# seconds equal to the unit's value.
|
|
82
|
+
def unit=(value)
|
|
83
|
+
if value.respond_to?(:to_i)
|
|
84
|
+
@unit = value.to_i
|
|
85
|
+
else
|
|
86
|
+
raise TypeError, "Can't set a Duration's unit to a #{value.class.name} object."
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
def -(value)
|
|
90
|
+
if value.respond_to?(:to_i)
|
|
91
|
+
auto_class(Duration.new(@length - value.to_i))
|
|
92
|
+
else
|
|
93
|
+
raise TypeError, "Can't convert #{value.class.name} to an integer."
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
def +(value)
|
|
97
|
+
if value.respond_to?(:to_i)
|
|
98
|
+
auto_class(Duration.new(@length + value.to_i))
|
|
99
|
+
else
|
|
100
|
+
raise TypeError, "Can't convert #{value.class.name} to an integer."
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
def *(value)
|
|
104
|
+
if value.is_a?(Duration)
|
|
105
|
+
@length * value.length * value.unit
|
|
106
|
+
elsif value.respond_to?(:to_i)
|
|
107
|
+
auto_class(Duration.new(@length * value))
|
|
108
|
+
else
|
|
109
|
+
raise TypeError, "Can't convert #{value.class.name} to an integer."
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
def /(value)
|
|
113
|
+
if value.is_a?(Duration)
|
|
114
|
+
@length / (value.length * value.unit)
|
|
115
|
+
elsif value.respond_to?(:to_i)
|
|
116
|
+
auto_class(Duration.new(@length / value))
|
|
117
|
+
else
|
|
118
|
+
raise TypeError, "Can't convert #{value.class.name} to an integer."
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
def in_weeks
|
|
122
|
+
Duration.new(@length.to_f / Week.length, Week.length)
|
|
123
|
+
end
|
|
124
|
+
def in_days
|
|
125
|
+
Duration.new(@length.to_f / Day.length, Day.length)
|
|
126
|
+
end
|
|
127
|
+
def in_hours
|
|
128
|
+
Duration.new(@length.to_f / Hour.length, Hour.length)
|
|
129
|
+
end
|
|
130
|
+
def in_minutes
|
|
131
|
+
Duration.new(@length.to_f / Minute.length, Minute.length)
|
|
132
|
+
end
|
|
133
|
+
def in_seconds
|
|
134
|
+
Duration.new(@length.to_f / Second.length, Second.length)
|
|
135
|
+
end
|
|
136
|
+
def weeks
|
|
137
|
+
@length.to_f / Week.length
|
|
138
|
+
end
|
|
139
|
+
def days
|
|
140
|
+
@length.to_f / Day.length
|
|
141
|
+
end
|
|
142
|
+
def hours
|
|
143
|
+
@length.to_f / Hour.length
|
|
144
|
+
end
|
|
145
|
+
def minutes
|
|
146
|
+
@length.to_f / Minute.length
|
|
147
|
+
end
|
|
148
|
+
def seconds
|
|
149
|
+
@length.to_f / Second.length
|
|
150
|
+
end
|
|
151
|
+
# * * * * * * * * * * * * * * * * * * * * *
|
|
152
|
+
|
|
153
|
+
# * * * * * * * * * * * * * * * * * * * * * * *
|
|
154
|
+
# A Duration can be 'anchored' to a START_TIME
|
|
155
|
+
# -This start_time is a Time object
|
|
156
|
+
def start_time=(value)
|
|
157
|
+
if value.is_a?(Time) || value.is_a?(DateTime)
|
|
158
|
+
@start_time = value.to_time
|
|
159
|
+
else
|
|
160
|
+
raise TypeError, "A Duration's start_time must be a Time or DateTime object."
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
def end_time=(value)
|
|
164
|
+
if value.is_a?(Time) || value.is_a?(DateTime)
|
|
165
|
+
@start_time = value.to_time - self #Subtracts this duration from the end_time to get the start_time
|
|
166
|
+
else
|
|
167
|
+
raise TypeError, "A Duration's end_time must be a Time or DateTime object."
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
def end_time
|
|
171
|
+
@start_time + self
|
|
172
|
+
end
|
|
173
|
+
def anchored?
|
|
174
|
+
!self.start_time.nil?
|
|
175
|
+
end
|
|
176
|
+
# * * * * * * * * * * * * * * * * * * * * * * *
|
|
177
|
+
|
|
178
|
+
# * * * * * * * * * * * * * * * * * * * * * * * *
|
|
179
|
+
# Calculations using Duration as an intermediate
|
|
180
|
+
def from(time)
|
|
181
|
+
time + @length
|
|
182
|
+
end
|
|
183
|
+
def before(time)
|
|
184
|
+
time - @length
|
|
185
|
+
end
|
|
186
|
+
def from_now
|
|
187
|
+
self.from(Time.now)
|
|
188
|
+
end
|
|
189
|
+
def ago
|
|
190
|
+
self.before(Time.now)
|
|
191
|
+
end
|
|
192
|
+
def starting(time)
|
|
193
|
+
self.start_time = time
|
|
194
|
+
self
|
|
195
|
+
end
|
|
196
|
+
def ending(time)
|
|
197
|
+
self.end_time = time
|
|
198
|
+
self
|
|
199
|
+
end
|
|
200
|
+
# * * * * * * * * * * * * * * * * * * * * * * * *
|
|
201
|
+
|
|
202
|
+
# * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
203
|
+
# A Duration can be treated as a 'collection' of units
|
|
204
|
+
def each_week(&block)
|
|
205
|
+
self.each(Week.length,&block)
|
|
206
|
+
end
|
|
207
|
+
def each_day(&block)
|
|
208
|
+
self.each(Day.length,&block)
|
|
209
|
+
end
|
|
210
|
+
def each_hour(&block)
|
|
211
|
+
self.each(Hour.length,&block)
|
|
212
|
+
end
|
|
213
|
+
def each_minute(&block)
|
|
214
|
+
self.each(Minute.length,&block)
|
|
215
|
+
end
|
|
216
|
+
def each_second(&block)
|
|
217
|
+
self.each(Second.length,&block)
|
|
218
|
+
end
|
|
219
|
+
def collect(use_unit=self.class.length,&block)
|
|
220
|
+
ary = []
|
|
221
|
+
self.each(use_unit) do |x|
|
|
222
|
+
ary << (block_given? ? yield(x) : x)
|
|
223
|
+
end
|
|
224
|
+
ary
|
|
225
|
+
end
|
|
226
|
+
def each(use_unit=self.class.length)
|
|
227
|
+
remainder = @length.to_f % use_unit
|
|
228
|
+
ret = []
|
|
229
|
+
if self.start_time.nil?
|
|
230
|
+
(@length.to_f / use_unit).to_i.times do |i|
|
|
231
|
+
ret << Duration.new(1, use_unit)
|
|
232
|
+
yield(ret[-1])
|
|
233
|
+
end
|
|
234
|
+
else
|
|
235
|
+
(@length.to_f / use_unit).to_i.times do |i|
|
|
236
|
+
ret << Duration.new(1, use_unit, (self.start_time + (use_unit * i)))
|
|
237
|
+
yield(ret[-1])
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
if remainder > 0
|
|
241
|
+
ret << (self.start_time.nil? ? Duration.new(remainder, 1) : Duration.new(remainder, 1, (self.start_time + @length - remainder)))
|
|
242
|
+
yield(ret[-1])
|
|
243
|
+
end
|
|
244
|
+
ret
|
|
245
|
+
end
|
|
246
|
+
# * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
247
|
+
|
|
248
|
+
# * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
249
|
+
# Through some ingenious metacoding (see 'def bind_object_method') below,
|
|
250
|
+
# it is possible to create a new method on a Duration object
|
|
251
|
+
# to a method on another object, in order to gather information
|
|
252
|
+
# based on the duration mentioned.
|
|
253
|
+
def create_find_within_method_for(other, method_name, other_method_name)
|
|
254
|
+
self.bind_object_method(other, method_name, other_method_name, [[], ['self.start_time', 'self.end_time']])
|
|
255
|
+
end
|
|
256
|
+
def self.create_find_within_method_for(other, method_name, other_method_name)
|
|
257
|
+
self.bind_class_object_method(other, method_name, other_method_name, [[], ['self.start_time', 'self.end_time']])
|
|
258
|
+
end
|
|
259
|
+
# * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
260
|
+
|
|
261
|
+
def method_missing(method_name, *args)
|
|
262
|
+
# Delegate any missing methods to the start_time Time object, if we have a start_time and the method exists there.
|
|
263
|
+
return self.start_time.send(method_name, *args) if self.anchored? && self.start_time.respond_to?(method_name)
|
|
264
|
+
super
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
private
|
|
268
|
+
def auto_class(obj=self)
|
|
269
|
+
new_obj = case obj.unit
|
|
270
|
+
when 1
|
|
271
|
+
obj.class.name == 'Seconds' ? obj : (obj.length == 1 ? Second.new(obj.start_time) : Seconds.new(obj.length,obj.start_time))
|
|
272
|
+
when 60
|
|
273
|
+
obj.class.name == 'Minutes' ? obj : (obj.length == 1 ? Minute.new(obj.start_time) : Minutes.new(obj.length,obj.start_time))
|
|
274
|
+
when 3600
|
|
275
|
+
obj.class.name == 'Hours' ? obj : (obj.length == 1 ? Hour.new(obj.start_time) : Hours.new(obj.length,obj.start_time))
|
|
276
|
+
when 86400
|
|
277
|
+
obj.class.name == 'Days' ? obj : (obj.length == 1 ? Day.new(obj.start_time) : Days.new(obj.length,obj.start_time))
|
|
278
|
+
when 604800
|
|
279
|
+
obj.class.name == 'Weeks' ? obj : (obj.length == 1 ? Week.new(obj.start_time) : Weeks.new(obj.length,obj.start_time))
|
|
280
|
+
else
|
|
281
|
+
obj.class.name == 'Duration' ? obj : Duration.new(obj.length,obj.unit,obj.start_time,{:auto_class => false})
|
|
282
|
+
end
|
|
283
|
+
# Now, auto-transform class if possible:
|
|
284
|
+
case
|
|
285
|
+
when !['Weeks', 'Week'].include?(new_obj.class.name) && new_obj.to_i.remainder(Week.length) == 0
|
|
286
|
+
new_obj.to_i == Week.length ? Week.new(new_obj.start_time) : Weeks.new(new_obj.to_f / Week.length,new_obj.start_time)
|
|
287
|
+
when !['Weeks', 'Week', 'Days', 'Day'].include?(new_obj.class.name) && new_obj.to_i.remainder(Day.length) == 0
|
|
288
|
+
new_obj.to_i == Day.length ? Day.new(new_obj.start_time) : Days.new(new_obj.to_f / Day.length,new_obj.start_time)
|
|
289
|
+
when !['Weeks', 'Week', 'Days', 'Day', 'Hours', 'Hour'].include?(new_obj.class.name) && new_obj.to_i.remainder(Hour.length) == 0
|
|
290
|
+
new_obj.to_i == Hour.length ? Hour.new(new_obj.start_time) : Hours.new(new_obj.to_f / Hour.length,new_obj.start_time)
|
|
291
|
+
when !['Weeks', 'Week', 'Days', 'Day', 'Hours', 'Hour', 'Minutes', 'Minute'].include?(new_obj.class.name) && new_obj.to_f.remainder(Minute.length) == 0
|
|
292
|
+
new_obj.to_i == Minute.length ? Minute.new(new_obj.start_time) : Minutes.new(new_obj.to_f / Minute.length,new_obj.start_time)
|
|
293
|
+
else
|
|
294
|
+
new_obj
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
class Weeks < Duration
|
|
299
|
+
def initialize(count=1,start_time=nil)
|
|
300
|
+
super(count,Week.length,start_time)
|
|
301
|
+
end
|
|
302
|
+
def self.length
|
|
303
|
+
604800
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
class Week < Weeks
|
|
307
|
+
def initialize(start_time=nil)
|
|
308
|
+
super(1,start_time)
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
class Days < Duration
|
|
312
|
+
def initialize(count=1,start_time=nil)
|
|
313
|
+
super(count,Day.length,start_time)
|
|
314
|
+
end
|
|
315
|
+
def self.length
|
|
316
|
+
86400
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
class Day < Days
|
|
320
|
+
def initialize(start_time=nil)
|
|
321
|
+
super(1,start_time)
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
class Hours < Duration
|
|
325
|
+
def initialize(count=1,start_time=nil)
|
|
326
|
+
super(count,Hour.length,start_time)
|
|
327
|
+
end
|
|
328
|
+
def self.length
|
|
329
|
+
3600
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
class Hour < Hours
|
|
333
|
+
def initialize(start_time=nil)
|
|
334
|
+
super(1,start_time)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
class Minutes < Duration
|
|
338
|
+
def initialize(count=1,start_time=nil)
|
|
339
|
+
super(count,Minute.length,start_time)
|
|
340
|
+
end
|
|
341
|
+
def self.length
|
|
342
|
+
60
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
class Minute < Minutes
|
|
346
|
+
def initialize(start_time=nil)
|
|
347
|
+
super(1,start_time)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
class Seconds < Duration
|
|
351
|
+
def initialize(count=1,start_time=nil)
|
|
352
|
+
super(count,Second.length,start_time)
|
|
353
|
+
end
|
|
354
|
+
def self.length
|
|
355
|
+
1
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
class Second < Seconds
|
|
359
|
+
def initialize(start_time=nil)
|
|
360
|
+
super(1,start_time)
|
|
361
|
+
end
|
|
362
|
+
end
|