quickbooks_api 0.0.7 → 0.1.0

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.
@@ -0,0 +1,48 @@
1
+ class Hash
2
+
3
+ def path_to_nested_key(key)
4
+ self.each do |k,v|
5
+ path = [k]
6
+ if k == key
7
+ return path
8
+ elsif v.is_a? Hash
9
+ nested_path = v.path_to_nested_key(key)
10
+ nested_path ? (return path + nested_path) : nil
11
+ end
12
+ end
13
+ return nil
14
+ end
15
+
16
+ def self.nest(path, value)
17
+ hash_constructor = lambda { |h, k| h[k] = Hash.new(&hash_constructor) }
18
+ nested_hash = Hash.new(&hash_constructor)
19
+
20
+ last_key = path.last
21
+ path.inject(nested_hash) { |h, k| (k == last_key) ? h[k] = value : h[k] }
22
+ nested_hash
23
+ end
24
+
25
+ end
26
+
27
+ class Class
28
+ def simple_name
29
+ self.to_s.split("::").last
30
+ end
31
+ end
32
+
33
+ class Object
34
+ def not_blank?
35
+ !self.blank?
36
+ end
37
+ end
38
+
39
+ class File
40
+ def self.read_from_unknown(file)
41
+ case file
42
+ when String
43
+ File.read(file)
44
+ when IO
45
+ file.read
46
+ end
47
+ end
48
+ end
@@ -4,29 +4,32 @@ describe Quickbooks::API do
4
4
 
5
5
  describe "interface" do
6
6
 
7
- it "should initialize" do
7
+ it "should initialize api instance" do
8
8
  end
9
9
 
10
- it "should create ruby wrapper objects for any qbxml input" do
10
+ it "should return cached instance for consecutive api requests" do
11
11
  end
12
12
 
13
- it "should convert ruby wrapper objects back to qbxml" do
13
+ it "should create qbxml object from qbxml input" do
14
14
  end
15
15
 
16
- end
17
-
18
- describe "helpers" do
16
+ it "should create qbxml object from hash input" do
17
+ end
19
18
 
20
- it "should load the schema" do
19
+ it "should convert qbxml input to hash output" do
21
20
  end
22
21
 
23
- it "should rebuild the schema" do
22
+ it "should convert hash input to qbxml output" do
24
23
  end
25
24
 
26
- it "should write the schema to disk" do
25
+ end
26
+
27
+ describe "helpers" do
28
+
29
+ it "should load the schema into memory during initialization" do
27
30
  end
28
31
 
29
- it "should find a nested qbxml hash" do
32
+ it "should load the container template into memory before initialization" do
30
33
  end
31
34
 
32
35
  end
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
2
 
3
- describe Quickbooks::Support::ClassBuilder do
3
+ describe Quickbooks::Parser::ClassBuilder do
4
4
 
5
5
  it "should add a type checked attribute accessor to a class" do
6
6
  end
@@ -0,0 +1,72 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe Quickbooks::Config do
4
+
5
+ #describe "configuration helpers" do
6
+
7
+ #it "should return the supported schema types" do
8
+ #valid_schema_types.should be_an_instance_of(Array)
9
+ #valid_schema_types.include?(:qb).should be_true
10
+ #valid_schema_types.include?(:qbpos).should be_true
11
+ #end
12
+
13
+ #it "should check if a particular schema type is supported" do
14
+ #self.stub!(:schema_type => :qb)
15
+ #valid_schema_type?.should be_true
16
+ #self.stub!(:schema_type => :qbpos)
17
+ #valid_schema_type?.should be_true
18
+ #self.stub!(:schema_type => :doesntexist)
19
+ #valid_schema_type?.should == false
20
+ #end
21
+
22
+ #it "should determine the dtd file path for any supported schema type" do
23
+ #self.stub!(:schema_type => :qb)
24
+ #File.exists?(dtd_file).should be_true
25
+ #self.stub!(:schema_type => :qbpos)
26
+ #File.exists?(dtd_file).should be_true
27
+ #end
28
+
29
+ #it "should determine the namespace for any supported schema type" do
30
+ #self.stub!(:schema_type => :qb)
31
+ #schema_namespace.should be_a_kind_of(Module)
32
+ #self.stub!(:schema_type => :qbpos)
33
+ #schema_namespace.should be_a_kind_of(Module)
34
+ #end
35
+
36
+ #it "should determine the container class for any supported schema type" do
37
+ #self.stub!(:schema_type => :qb)
38
+ #container_class.should == 'QBXML'
39
+ #self.stub!(:schema_type => :qbpos)
40
+ #schema_namespace.should == 'QBPOSXML'
41
+ #end
42
+
43
+ #end
44
+
45
+ #describe "other helpers" do
46
+
47
+ #before :all do
48
+ #@qb_api = Quickbooks::API.new(:qb)
49
+ #@qbpos_api = Quickbooks::API.new(:qbpos)
50
+ #end
51
+
52
+ #it "should return all the cached classes" do
53
+ #self.stub!(:schema_type => :qb)
54
+ #cached_classes.should be_an_instance_of(Array)
55
+ #cached_classes.empty?.should be_false
56
+ #cached_classes.include?(container_class).should be_true
57
+ #self.stub!(:schema_type => :qbpos)
58
+ #cached_classes.should be_an_instance_of(Array)
59
+ #cached_classes.empty?.should be_false
60
+ #cached_classes.include?(container_class).should be_true
61
+ #end
62
+
63
+ #it "should check if a particular class is cached" do
64
+ #self.stub!(:schema_type => :qb)
65
+ #is_cached_class?(Quickbooks::QBXML::QBXML).should be_true
66
+ #self.stub!(:schema_type => :qbpos)
67
+ #is_cached_class?(Quickbooks::QBPOSXML::QBPOSXML).should be_true
68
+ #end
69
+
70
+ #end
71
+
72
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe Quickbooks::Support::Inflection do
4
+
5
+ #before :each do
6
+ #@klass = Nokogiri::XML::NodeSet
7
+ #stub_child = stub(:class => XML_TEXT)
8
+ #@stub_xml_node = stub(:name => "SomeNodeName", :children => [stub_child])
9
+ #@stub_xml_node.stub!(:is_a?).with(anything).and_return(false)
10
+ #@stub_xml_node.stub!(:is_a?).with(XML_ELEMENT).and_return(true)
11
+ #end
12
+
13
+ #it "should convert a class or xml element name to underscored" do
14
+ #underscore(@klass).should == 'node_set'
15
+ #underscore(@stub_xml_node).should == 'some_node_name'
16
+ #end
17
+
18
+ end
@@ -1,20 +1,8 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
2
 
3
- describe Quickbooks::Support::Logger do
3
+ describe Quickbooks::Logger do
4
4
 
5
5
  it "should initialize an ActiveSupport::BufferedLogger" do
6
6
  end
7
7
 
8
- it "should log to a thread specific buffer" do
9
- end
10
-
11
- it "should print the contents of the log buffer" do
12
- end
13
-
14
- it "should indent, unindent, and reset indentation" do
15
- end
16
-
17
- it "should change the format appropriately when the formatter is changed" do
18
- end
19
-
20
8
  end
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe "Monkey Patches" do
4
+
5
+ before :each do
6
+ end
7
+
8
+ #it "should convert a full class name to a simple class name" do
9
+ #@klass.simple_name.should == 'NodeSet'
10
+ #end
11
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe Quickbooks::Parser::QbxmlBase do
4
+
5
+ it "should have a type conversion map with all qb types" do
6
+ end
7
+
8
+ it "should initialize a qbxml object given an attribute hash" do
9
+ end
10
+
11
+ it "should generate qbxml from a qbxml object" do
12
+ end
13
+
14
+ it "should a hash of attributes for the qbxml object" do
15
+ end
16
+
17
+ it "should return the attribute names of the qbxml class" do
18
+ end
19
+
20
+ it "should return the type map of the qbxml class" do
21
+ end
22
+
23
+ end
@@ -0,0 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe Quickbooks::Parser::XMLGeneration do
4
+
5
+ end
@@ -0,0 +1,36 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+
3
+ describe Quickbooks::Parser::XMLParsing do
4
+
5
+ #it "should set useful parsing constants" do
6
+ #XML_DOCUMENT.should == Nokogiri::XML::Document
7
+ #XML_NODE_SET.should == Nokogiri::XML::NodeSet
8
+ #XML_NODE.should == Nokogiri::XML::Node
9
+ #XML_ELEMENT.should == Nokogiri::XML::Element
10
+ #XML_COMMENT= Nokogiri::XML::Comment
11
+ #XML_TEXT.should == Nokogiri::XML::Text
12
+ #end
13
+
14
+ #describe "xml parsing helpers" do
15
+
16
+ #before :each do
17
+ #@klass = Nokogiri::XML::NodeSet
18
+ #stub_child = stub(:class => XML_TEXT)
19
+ #@stub_xml_node = stub(:name => "SomeNodeName", :children => [stub_child])
20
+ #@stub_xml_node.stub!(:is_a?).with(anything).and_return(false)
21
+ #@stub_xml_node.stub!(:is_a?).with(XML_ELEMENT).and_return(true)
22
+ #end
23
+
24
+ #it "should check if a node is a leaf node" do
25
+ #is_leaf_node?(@stub_xml_node).should be_true
26
+ #end
27
+
28
+ #end
29
+
30
+ #it "should check if a class is already defined in a particular namespace" do
31
+ #end
32
+
33
+ #it "should cleanup qbxml" do
34
+ #end
35
+
36
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quickbooks_api
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 7
10
- version: 0.0.7
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Skryl
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-27 00:00:00 -05:00
18
+ date: 2011-06-30 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -46,22 +46,6 @@ dependencies:
46
46
  version: "0"
47
47
  type: :runtime
48
48
  version_requirements: *id002
49
- - !ruby/object:Gem::Dependency
50
- name: ruby2ruby
51
- prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
- none: false
54
- requirements:
55
- - - "="
56
- - !ruby/object:Gem::Version
57
- hash: 29
58
- segments:
59
- - 1
60
- - 2
61
- - 1
62
- version: 1.2.1
63
- type: :runtime
64
- version_requirements: *id003
65
49
  description: A QuickBooks QBXML wrapper for Ruby
66
50
  email: rut216@gmail.com
67
51
  executables: []
@@ -72,27 +56,33 @@ extra_rdoc_files: []
72
56
 
73
57
  files:
74
58
  - lib/quickbooks/api.rb
59
+ - lib/quickbooks/config.rb
75
60
  - lib/quickbooks/dtd_parser.rb
76
- - lib/quickbooks/qbxml_base.rb
61
+ - lib/quickbooks/logger.rb
62
+ - lib/quickbooks/parser/class_builder.rb
63
+ - lib/quickbooks/parser/qbxml_base.rb
64
+ - lib/quickbooks/parser/xml_generation.rb
65
+ - lib/quickbooks/parser/xml_parsing.rb
77
66
  - lib/quickbooks/qbxml_parser.rb
78
- - lib/quickbooks/support/api.rb
79
- - lib/quickbooks/support/class_builder.rb
80
- - lib/quickbooks/support/logger.rb
81
- - lib/quickbooks/support/qbxml.rb
82
- - lib/quickbooks/support.rb
67
+ - lib/quickbooks/support/inflection.rb
68
+ - lib/quickbooks/support/monkey_patches.rb
83
69
  - lib/quickbooks.rb
84
70
  - spec/quickbooks/api_spec.rb
85
71
  - spec/quickbooks/class_builder_spec.rb
72
+ - spec/quickbooks/config_spec.rb
86
73
  - spec/quickbooks/dtd_parser_spec.rb
74
+ - spec/quickbooks/inflection_spec.rb
87
75
  - spec/quickbooks/logger_spec.rb
76
+ - spec/quickbooks/monkey_patches_spec.rb
77
+ - spec/quickbooks/qbxml_base_spec.rb
88
78
  - spec/quickbooks/qbxml_parser_spec.rb
89
- - spec/quickbooks/qbxml_spec.rb
90
79
  - spec/quickbooks/spec_helper.rb
91
- - spec/quickbooks/support_spec.rb
80
+ - spec/quickbooks/xml_generation_spec.rb
81
+ - spec/quickbooks/xml_parsing_spec.rb
92
82
  - xml_schema/qbposxmlops30.xml
93
83
  - xml_schema/qbxmlops70.xml
94
- - ruby_schema/qb/templates/.placeholder
95
- - ruby_schema/qbpos/templates/.placeholder
84
+ - README
85
+ - TODO
96
86
  has_rdoc: true
97
87
  homepage: http://github.com/skryl
98
88
  licenses: []
@@ -1,212 +0,0 @@
1
- # inheritance base for schema classes
2
- class Quickbooks::QbxmlBase
3
- include Quickbooks::Support
4
- include Quickbooks::Support::QBXML
5
-
6
- extend Quickbooks::Support
7
- extend Quickbooks::Support::API
8
-
9
- QB_TYPE_CONVERSION_MAP= {
10
- "AMTTYPE" => lambda {|d| d ? Float(d) : 0.0 },
11
- #"BOOLTYPE" => lambda {|d| d ? (d == 'True' ? true : false) : false },
12
- "BOOLTYPE" => lambda {|d| d ? String(d) : '' },
13
- "DATETIMETYPE" => lambda {|d| d ? Time.parse(d).xmlschema : Time.now.xmlschema },
14
- "DATETYPE" => lambda {|d| d ? Date.parse(d).xmlschema : Date.today.xmlschema },
15
- "ENUMTYPE" => lambda {|d| d ? String(d) : ''},
16
- "FLOATTYPE" => lambda {|d| d ? Float(d) : 0.0},
17
- "GUIDTYPE" => lambda {|d| d ? String(d) : ''},
18
- "IDTYPE" => lambda {|d| d ? String(d) : ''},
19
- "INTTYPE" => lambda {|d| d ? Integer(d) : 0 },
20
- "PERCENTTYPE" => lambda {|d| d ? Float(d) : 0.0 },
21
- "PRICETYPE" => lambda {|d| d ? Float(d) : 0.0 },
22
- "QUANTYPE" => lambda {|d| d ? Integer(d.to_i) : 0 },
23
- "STRTYPE" => lambda {|d| d ? String(d) : ''},
24
- "TIMEINTERVALTYPE" => lambda {|d| d ? String(d) : ''}
25
- }
26
-
27
-
28
- def initialize(params = nil)
29
- return unless params.is_a?(Hash)
30
- params.each do |k,v|
31
- if self.respond_to?(k)
32
- expected_type = self.class.send("#{k}_type")
33
- v = \
34
- case v
35
- when Hash
36
- expected_type.new(v)
37
- when Array
38
- v.inject([]) { |a,i| a << expected_type.new(i) }
39
- else v
40
- end
41
- self.send("#{k}=", v)
42
- end
43
- end
44
- end
45
-
46
-
47
- def to_qbxml
48
- xml_doc = Nokogiri::XML(self.class.xml_template)
49
- root = xml_doc.root
50
- log.debug "to_qbxml#nodes_size: #{root.children.size}"
51
-
52
- # replace all children nodes of the template with populated data nodes
53
- xml_nodes = []
54
- root.children.each do |xml_template|
55
- next unless xml_template.is_a? XML_ELEMENT
56
- attr_name = to_attribute_name(xml_template)
57
- log.debug "to_qbxml#attr_name: #{attr_name}"
58
-
59
- val = self.send(attr_name)
60
- next unless val && !val.blank?
61
-
62
- case val
63
- when Array
64
- xml_nodes += build_qbxml_nodes(xml_template, val)
65
- else
66
- xml_nodes << build_qbxml_node(xml_template, val)
67
- end
68
- log.debug "to_qbxml#val: #{val}"
69
- end
70
-
71
- log.debug "to_qbxml#xml_nodes_size: #{xml_nodes.size}"
72
- root.children = xml_nodes.join('')
73
- root.to_s
74
- end
75
-
76
-
77
- def self.template(recursive = false, use_disk_cache = false, reload = false)
78
- if recursive
79
- @template = (!reload && @template) || load_template(true, use_disk_cache)
80
- else build_template(false)
81
- end
82
- end
83
-
84
-
85
- def self.attribute_names
86
- instance_methods(false).reject { |m| m[-1..-1] == '=' || m =~ /_xml_class/}
87
- end
88
-
89
-
90
- def inner_attributes(parent = nil)
91
- attrs = attributes(false)
92
- values = attrs.values.compact
93
-
94
- if values.empty?
95
- {}
96
- elsif values.first.is_a?(Array)
97
- attributes
98
- elsif values.size > 1
99
- parent.attributes
100
- else
101
- first_val = values.first
102
- if first_val.respond_to?(:inner_attributes)
103
- first_val.inner_attributes(self)
104
- else
105
- parent.attributes
106
- end
107
- end
108
- end
109
-
110
-
111
- def attributes(recursive = true)
112
- self.class.attribute_names.inject({}) do |h, m|
113
- val = self.send(m)
114
- if val
115
- unless recursive
116
- h[m] = val
117
- else
118
- h[m] = nested_attributes(val)
119
- end
120
- end; h
121
- end
122
- end
123
-
124
-
125
- private
126
-
127
- # qbxml conversion
128
-
129
- def nested_attributes(val)
130
- case val
131
- when Quickbooks::QbxmlBase
132
- val.attributes
133
- when Array
134
- val.inject([]) do |a, obj|
135
- case obj
136
- when Quickbooks::QbxmlBase
137
- a << obj.attributes
138
- else a << obj
139
- end
140
- end
141
- else val
142
- end
143
- end
144
-
145
- def build_qbxml_node(node, val)
146
- case val
147
- when Quickbooks::QbxmlBase
148
- val.to_qbxml
149
- else
150
- node.children = val.to_s
151
- node
152
- end
153
- end
154
-
155
- def build_qbxml_nodes(node, val)
156
- val.inject([]) do |a, v|
157
- n = \
158
- case v
159
- when Quickbooks::QbxmlBase
160
- v.to_qbxml
161
- else
162
- clone_qbxml_node(node,v)
163
- end
164
- a << n
165
- end
166
- end
167
-
168
- def clone_qbxml_node(node, val)
169
- n = node.clone
170
- n.children = val.to_s
171
- n
172
- end
173
-
174
- # qbxml class templates
175
-
176
- def self.load_template(recursive = false, use_disk_cache = false)
177
- if use_disk_cache && File.exist?(template_cache_path)
178
- YAML.load(File.read(template_cache_path))
179
- else
180
- log.info "Warning: on disk template is missing, rebuilding..." if use_disk_cache
181
- template = build_template(recursive)
182
- dump_template(template) if use_disk_cache
183
- template
184
- end
185
- end
186
-
187
- def self.build_template(recursive = false)
188
- attribute_names.inject({}) do |h, a|
189
- attr_type = self.send("#{a}_type")
190
- h[a] = (is_cached_class?(attr_type) && recursive) ? attr_type.build_template(true): attr_type.to_s; h
191
- end
192
- end
193
-
194
- def self.dump_template(template)
195
- File.open(template_cache_path, 'w') do |f|
196
- f << template.to_yaml
197
- end
198
- end
199
-
200
- def self.template_cache_path
201
- "#{get_template_cache_path}/#{to_attribute_name(self)}.yml"
202
- end
203
-
204
- def self.schema_type
205
- namespace = self.to_s.split("::")[1]
206
- API::SCHEMA_MAP.find do |k,v|
207
- simple_class_name(v[:namespace]) == namespace
208
- end.first
209
- end
210
-
211
-
212
- end