jm81-qbfc 0.3.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.
Files changed (91) hide show
  1. data/.gitignore +11 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +81 -0
  5. data/VERSION +1 -0
  6. data/init.rb +3 -0
  7. data/install.rb +1 -0
  8. data/lib/qbfc.rb +41 -0
  9. data/lib/qbfc/base.rb +82 -0
  10. data/lib/qbfc/element.rb +243 -0
  11. data/lib/qbfc/entities/generated.rb +8 -0
  12. data/lib/qbfc/entity.rb +11 -0
  13. data/lib/qbfc/info.rb +42 -0
  14. data/lib/qbfc/infos/generated.rb +9 -0
  15. data/lib/qbfc/item.rb +29 -0
  16. data/lib/qbfc/items/generated.rb +11 -0
  17. data/lib/qbfc/list.rb +84 -0
  18. data/lib/qbfc/lists/account.rb +24 -0
  19. data/lib/qbfc/lists/generated.rb +15 -0
  20. data/lib/qbfc/lists/qb_class.rb +25 -0
  21. data/lib/qbfc/modifiable.rb +31 -0
  22. data/lib/qbfc/ole_wrapper.rb +201 -0
  23. data/lib/qbfc/qb_collection.rb +26 -0
  24. data/lib/qbfc/qb_types.rb +18 -0
  25. data/lib/qbfc/qbfc_const.rb +14 -0
  26. data/lib/qbfc/report.rb +95 -0
  27. data/lib/qbfc/reports/aging.rb +13 -0
  28. data/lib/qbfc/reports/budget_summary.rb +13 -0
  29. data/lib/qbfc/reports/custom_detail.rb +9 -0
  30. data/lib/qbfc/reports/custom_summary.rb +9 -0
  31. data/lib/qbfc/reports/general_detail.rb +44 -0
  32. data/lib/qbfc/reports/general_summary.rb +33 -0
  33. data/lib/qbfc/reports/job.rb +14 -0
  34. data/lib/qbfc/reports/payroll_detail.rb +13 -0
  35. data/lib/qbfc/reports/payroll_summary.rb +13 -0
  36. data/lib/qbfc/reports/rows.rb +51 -0
  37. data/lib/qbfc/reports/time.rb +12 -0
  38. data/lib/qbfc/request.rb +295 -0
  39. data/lib/qbfc/session.rb +147 -0
  40. data/lib/qbfc/terms.rb +10 -0
  41. data/lib/qbfc/terms/generated.rb +10 -0
  42. data/lib/qbfc/transaction.rb +110 -0
  43. data/lib/qbfc/transactions/generated.rb +25 -0
  44. data/lib/qbfc/voidable.rb +11 -0
  45. data/spec/fixtures/test.lgb +0 -0
  46. data/spec/fixtures/test.qbw +0 -0
  47. data/spec/fixtures/test.qbw.TLG +0 -0
  48. data/spec/integration/add_spec.rb +31 -0
  49. data/spec/integration/base_spec.rb +18 -0
  50. data/spec/integration/belongs_to_spec.rb +64 -0
  51. data/spec/integration/company_spec.rb +30 -0
  52. data/spec/integration/conditions_spec.rb +59 -0
  53. data/spec/integration/customer_spec.rb +46 -0
  54. data/spec/integration/element_finders_spec.rb +20 -0
  55. data/spec/integration/quick_test.rb +31 -0
  56. data/spec/integration/request_options_spec.rb +68 -0
  57. data/spec/rcov.opts +1 -0
  58. data/spec/spec.opts +6 -0
  59. data/spec/spec_helper.rb +62 -0
  60. data/spec/unit/base_spec.rb +138 -0
  61. data/spec/unit/element_finder_spec.rb +185 -0
  62. data/spec/unit/element_spec.rb +108 -0
  63. data/spec/unit/entities/generated_spec.rb +18 -0
  64. data/spec/unit/entity_spec.rb +18 -0
  65. data/spec/unit/info/generated_spec.rb +12 -0
  66. data/spec/unit/info_spec.rb +48 -0
  67. data/spec/unit/item_spec.rb +33 -0
  68. data/spec/unit/items/generated_spec.rb +16 -0
  69. data/spec/unit/list_finders_spec.rb +129 -0
  70. data/spec/unit/list_spec.rb +86 -0
  71. data/spec/unit/lists/account_spec.rb +20 -0
  72. data/spec/unit/lists/generated_spec.rb +15 -0
  73. data/spec/unit/lists/qb_class_spec.rb +9 -0
  74. data/spec/unit/modifiable_spec.rb +84 -0
  75. data/spec/unit/ole_wrapper_spec.rb +337 -0
  76. data/spec/unit/qb_collection_spec.rb +13 -0
  77. data/spec/unit/qbfc_const_spec.rb +10 -0
  78. data/spec/unit/qbfc_spec.rb +10 -0
  79. data/spec/unit/report_spec.rb +12 -0
  80. data/spec/unit/request_query_survey.txt +48 -0
  81. data/spec/unit/request_spec.rb +486 -0
  82. data/spec/unit/session_spec.rb +144 -0
  83. data/spec/unit/terms/generated_spec.rb +14 -0
  84. data/spec/unit/terms_spec.rb +18 -0
  85. data/spec/unit/transaction_finders_spec.rb +125 -0
  86. data/spec/unit/transaction_spec.rb +94 -0
  87. data/spec/unit/transactions/generated_spec.rb +20 -0
  88. data/spec/unit/voidable_spec.rb +32 -0
  89. data/tasks/qbfc_tasks.rake +4 -0
  90. data/uninstall.rb +1 -0
  91. metadata +180 -0
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+
3
+ module QBFC::Test
4
+ class BaseFind < QBFC::Element
5
+ is_base_class
6
+
7
+ ID_NAME = "ListID"
8
+
9
+ def self.qb_name
10
+ "Entity"
11
+ end
12
+ end
13
+
14
+ class ElementFind < QBFC::Element
15
+ def self.qb_name
16
+ "Check"
17
+ end
18
+ end
19
+ end
20
+
21
+ # An Element is a Transaction or a List; that is any QuickBooks objects that can
22
+ # be created, edited (possibly), deleted and read. Contrast to a Report or Info
23
+ # which are read-only.
24
+ describe QBFC::Element do
25
+
26
+ before(:each) do
27
+ @sess = mock(QBFC::Session)
28
+ @ole_wrapper = mock(QBFC::OLEWrapper)
29
+ @element = mock(QBFC::Test::ElementFind)
30
+
31
+ # Request related mocks
32
+ @request = mock("QBFC::Request")
33
+ @request.stub!(:kind_of?).with(QBFC::Request).and_return(true)
34
+ @request.stub!(:kind_of?).with(Hash).and_return(false)
35
+ @request.stub!(:dup).and_return(@request)
36
+ @response = mock("QBFC::Request#response")
37
+
38
+ # Filter mock
39
+ @filter = mock("QBFC::OLEWrapper#Filter")
40
+ @request.stub!(:filter).and_return(@filter)
41
+ @request.stub!(:add_limit)
42
+ @request.stub!(:filter_available?).and_return(true)
43
+ @request.stub!(:apply_options)
44
+ end
45
+
46
+ def setup_request
47
+ QBFC::Request.stub!(:new).and_return(@request)
48
+ @request.stub!(:response).and_return(@response)
49
+ @response.stub!(:GetAt).and_return(@ole_wrapper)
50
+ @response.stub!(:ole_methods).and_return(["GetAt"])
51
+ @response.stub!(:Count).and_return(2)
52
+
53
+ QBFC::Test::ElementFind.should_receive(:new).with(@sess, @ole_wrapper).at_least(:once).and_return(@element)
54
+ end
55
+
56
+ describe ".find" do
57
+
58
+ it "should find_by_unique_id if the 'what' argument is neither :all nor :first" do
59
+ QBFC::Test::ElementFind::should_receive(:find_by_unique_id).with(@sess, "123-456", {})
60
+ QBFC::Test::ElementFind::find(@sess, "123-456", {})
61
+ end
62
+
63
+ it "should return only first entry if 'what' argument is :first" do
64
+ setup_request
65
+ QBFC::Test::ElementFind::find(@sess, :first).should be(@element)
66
+ end
67
+
68
+ it "should set request#max_returned to 1 if :first" do
69
+ setup_request
70
+ @request.should_receive(:add_limit).with(1)
71
+ @request.stub!(:filter_available?).and_return(true)
72
+ QBFC::Test::ElementFind::find(@sess, :first)
73
+ end
74
+
75
+ it "should not set request#max_returned if not request.filter_available?" do
76
+ setup_request
77
+ @request.stub!(:filter_available?).and_return(false)
78
+ @request.should_not_receive(:add_limit)
79
+ QBFC::Test::ElementFind::find(@sess, :first)
80
+ end
81
+
82
+ it "should return an array if 'what' argument is :all" do
83
+ setup_request
84
+ @filter.should_not_receive(:max_returned=)
85
+ QBFC::Test::ElementFind::find(@sess, :all).should == [@element, @element]
86
+ end
87
+
88
+ it "should return nil if no elements are found unless finding :first" do
89
+ QBFC::Request.should_receive(:new).with(@sess, 'CheckQuery').and_return(@request)
90
+ @request.should_receive(:response).and_return(nil)
91
+ QBFC::Test::ElementFind::find(@sess, :first).should be_nil
92
+ end
93
+
94
+ it "should return an empty array if no elements are found when finding :all" do
95
+ QBFC::Request.should_receive(:new).with(@sess, 'CheckQuery').and_return(@request)
96
+ @request.should_receive(:response).and_return(nil)
97
+ QBFC::Test::ElementFind::find(@sess, :first).should be_nil
98
+ end
99
+
100
+ it "should call Base.parse_find_args" do
101
+ setup_request
102
+ QBFC::Test::ElementFind::should_receive(:parse_find_args).with({:option => true})
103
+ QBFC::Test::ElementFind::find(@sess, :all, {:option => true})
104
+ end
105
+
106
+ it "applies options to request" do
107
+ setup_request
108
+ @request.should_receive(:apply_options).with({:owner_id => 0})
109
+ QBFC::Test::ElementFind::find(@sess, :first, :owner_id => 0)
110
+ end
111
+
112
+ it "should get request#response" do
113
+ setup_request
114
+ @request.should_receive(:response).and_return(@response)
115
+ QBFC::Test::ElementFind::find(@sess, :first)
116
+ end
117
+
118
+ it "should call base_class_find for base classes" do
119
+ QBFC::Request.stub!(:new).and_return(@request)
120
+ QBFC::Test::BaseFind.should_receive(:base_class_find).with(@sess, :first, @request, {}).and_return(@element)
121
+ QBFC::Test::BaseFind::find(@sess, :first, {}).should be(@element)
122
+ end
123
+
124
+ it "should not call base_class_find for non-base classes" do
125
+ setup_request
126
+ QBFC::Test::ElementFind.should_not_receive(:base_class_find)
127
+ QBFC::Test::ElementFind::find(@sess, :first, {})
128
+ end
129
+ end
130
+
131
+ describe ".base_class_find" do
132
+ before(:each) do
133
+ @include_list = mock("IncludeRetElementList")
134
+ @request.stub!(:IncludeRetElementList).and_return(@include_list)
135
+ @include_list.stub!(:Add).with("ListID")
136
+ @request.stub!(:response).and_return(@response)
137
+ QBFC::Request.stub!(:new).and_return(@request)
138
+
139
+ @element = mock(QBFC::Test::ElementFind)
140
+ @base_element = mock(QBFC::Test::BaseFind)
141
+ @customer_ret = mock("CustomerRet")
142
+ @list_id = mock("ListID")
143
+ @base_element.stub!(:ole_methods).and_return(["VendorRet", "CustomerRet"])
144
+ @base_element.stub!(:VendorRet).and_return(nil)
145
+ @base_element.stub!(:CustomerRet).and_return(@customer_ret)
146
+ @customer_ret.stub!(:ListID).and_return(@list_id)
147
+ @list_id.stub!(:GetValue).and_return("123-456")
148
+ QBFC::Customer.stub!(:find_by_id).and_return(@element)
149
+
150
+ @response.stub!(:GetAt).and_return(@base_element)
151
+ @response.stub!(:Count).and_return(2)
152
+ end
153
+
154
+ it "should request only ListID" do
155
+ @include_list.should_receive(:Add).with("ListID")
156
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {})
157
+ end
158
+
159
+ it "should send class ChildList::find_by_id with ListID and find options for each" do
160
+ @base_element.should_receive(:CustomerRet).at_least(:once).and_return(@customer_ret)
161
+ @customer_ret.should_receive(:ListID).at_least(:once).and_return(@list_id)
162
+ @list_id.should_receive(:GetValue).at_least(:once).and_return("789-012")
163
+ QBFC::Customer.should_receive(:find_by_id).at_least(:once).with(@sess, "789-012", {}).and_return(@element)
164
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be(@element)
165
+ end
166
+
167
+ it "should return nil if no records and not :all" do
168
+ @request.should_receive(:response).and_return(nil)
169
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be_nil
170
+ end
171
+
172
+ it "should return nil if no records and not :all" do
173
+ @request.should_receive(:response).and_return(nil)
174
+ QBFC::Test::BaseFind.find(@sess, :all, @request, {}).should == []
175
+ end
176
+
177
+ it "should return single record unless :all" do
178
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be(@element)
179
+ end
180
+
181
+ it "should return Array if :all" do
182
+ QBFC::Test::BaseFind.find(@sess, :all, @request, {}).should == [@element, @element]
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ module QBFC::Test
4
+ class BaseKlass < QBFC::Element
5
+ is_base_class
6
+ end
7
+
8
+ class NormalKlass < QBFC::Element
9
+ end
10
+ end
11
+
12
+ # An Element is a Transaction or a List; that is any QuickBooks objects that can
13
+ # be created, edited (possibly), deleted and read. Contrast to a Report or Info
14
+ # which are read-only.
15
+ describe QBFC::Element do
16
+
17
+ before(:each) do
18
+ @sess = mock(QBFC::Session)
19
+ @ole_wrapper = mock(QBFC::OLEWrapper)
20
+ @ole_object = mock(WIN32OLE)
21
+ @ole_methods = ["FullName", "DataExtRetList"]
22
+ @element = QBFC::Test::NormalKlass.new(@sess, @ole_wrapper)
23
+ end
24
+
25
+ describe "#initialize" do
26
+ it "should set up add request if ole_object is nil" do
27
+ @request = mock(QBFC::Request)
28
+ @request.should_receive(:ole_object).and_return(@ole_object)
29
+ QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
30
+ QBFC::Test::NormalKlass.new(@sess)
31
+ end
32
+
33
+ it "should assign the Add request as the @setter" do
34
+ @request = mock(QBFC::Request)
35
+ @request.stub!(:ole_object).and_return(@ole_object)
36
+ QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
37
+ QBFC::Test::NormalKlass.new(@sess).
38
+ instance_variable_get(:@setter).should == @request
39
+ end
40
+ end
41
+
42
+ describe "#new_record?" do
43
+ before(:each) do
44
+ @request = mock(QBFC::Request)
45
+ @request.stub!(:ole_object).and_return(@ole_object)
46
+ QBFC::Request.stub!(:new).with(@sess, "NormalKlassAdd").and_return(@request)
47
+ end
48
+
49
+ it "should return true if ole_object is an AddRq" do
50
+ QBFC::Test::NormalKlass.new(@sess).new_record?.should be_true
51
+ end
52
+
53
+ it "should return false if ole_object is from a QueryRq" do
54
+ @element.new_record?.should be_false
55
+ end
56
+ end
57
+
58
+ describe ".is_base_class? (and is_base_class macro)" do
59
+ it "should return true if Class is_base_class has been called" do
60
+ QBFC::Test::BaseKlass.is_base_class?.should be_true
61
+ QBFC::Test::NormalKlass.is_base_class?.should be_false
62
+ end
63
+ end
64
+
65
+ describe "#custom" do
66
+ before(:each) do
67
+ @data_ext = mock("QBFC::OLEWrapper#DataExtRet")
68
+ @data_ext_list = [@data_ext, @data_ext]
69
+ @ole_wrapper.stub!(:DataExtRetList).and_return(@data_ext_list)
70
+ @ole_wrapper.stub!(:data_ext).and_return(@data_ext_list)
71
+ end
72
+
73
+ it "should get custom fields" do
74
+ @data_ext.should_receive(:data_ext_name).and_return("Custom Field")
75
+ @data_ext.should_receive(:owner_id).and_return('0')
76
+ @data_ext.should_receive(:data_ext_value).and_return("Hello")
77
+
78
+ @element.custom("Custom Field").should == "Hello"
79
+ end
80
+
81
+ it "should return nil if there are no custom fields" do
82
+ @ole_wrapper.should_receive(:DataExtRetList).and_return(nil)
83
+
84
+ @element.custom("Custom Field").should be_nil
85
+ end
86
+
87
+ it "should return nil if the custom field is not found" do
88
+ @data_ext.should_receive(:data_ext_name).twice.and_return("Custom Field")
89
+
90
+ @element.custom("No Field").should be_nil
91
+ end
92
+ end
93
+
94
+ describe "#save" do
95
+ it "should submit the setter object" do
96
+ @request = mock(QBFC::Request)
97
+ @request.stub!(:ole_object).and_return(@ole_object)
98
+ QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
99
+ @request.should_receive(:submit)
100
+
101
+ QBFC::Test::NormalKlass.new(@sess).save
102
+ end
103
+
104
+ it "should raise an error if there is no setter object" do
105
+ lambda { @element.save}.should raise_error(QBFC::NotSavableError)
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "QBFC::Entity generated.rb" do
4
+
5
+ it "should generate classes" do
6
+ QBFC::Customer.superclass.should be(QBFC::Entity)
7
+ QBFC::Vendor.superclass.should be(QBFC::Entity)
8
+ QBFC::OtherName.superclass.should be(QBFC::Entity)
9
+ QBFC::Employee.superclass.should be(QBFC::Entity)
10
+ end
11
+
12
+ it "should include Modifiable in all classes" do
13
+ QBFC::Customer.included_modules.should include(QBFC::Modifiable)
14
+ QBFC::Vendor.included_modules.should include(QBFC::Modifiable)
15
+ QBFC::OtherName.included_modules.should include(QBFC::Modifiable)
16
+ QBFC::Employee.included_modules.should include(QBFC::Modifiable)
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe QBFC::Entity do
4
+
5
+ before(:each) do
6
+ @sess = mock(QBFC::Session)
7
+ @ole_wrapper = mock(QBFC::OLEWrapper)
8
+ end
9
+
10
+ it "is a base class" do
11
+ QBFC::Entity.is_base_class?.should be_true
12
+ end
13
+
14
+ describe ".find" do
15
+ it "should return subclass objects"
16
+ end
17
+
18
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "QBFC::Info generated.rb" do
4
+
5
+ it "should generate classes" do
6
+ QBFC::Company.superclass.should be(QBFC::Info)
7
+ QBFC::CompanyActivity.superclass.should be(QBFC::Info)
8
+ QBFC::Host.superclass.should be(QBFC::Info)
9
+ QBFC::Preferences.superclass.should be(QBFC::Info)
10
+ end
11
+
12
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ module QBFC::Test
4
+ class Info < QBFC::Info
5
+ def self.qb_name
6
+ "Company"
7
+ end
8
+ end
9
+ end
10
+
11
+ describe QBFC::Info do
12
+
13
+ before(:each) do
14
+ @sess = mock(QBFC::Session)
15
+ @ole_wrapper = mock(QBFC::OLEWrapper)
16
+ @info = mock(QBFC::Test::Info)
17
+
18
+ # Request related mocks
19
+ @request = mock("QBFC::Request")
20
+ @response = mock("QBFC::Request#response")
21
+
22
+ QBFC::Request.stub!(:new).with(@sess, 'CompanyQuery').and_return(@request)
23
+ @request.stub!(:response).and_return(@response)
24
+ QBFC::Test::Info.stub!(:new).with(@sess, @response).and_return(@info)
25
+ @request.stub!(:apply_options)
26
+ end
27
+
28
+ describe ".get" do
29
+ it "should create Request and get response" do
30
+ QBFC::Request.should_receive(:new).with(@sess, 'CompanyQuery').and_return(@request)
31
+ @request.should_receive(:response).and_return(@response)
32
+ QBFC::Test::Info.should_receive(:new).with(@sess, @response).and_return(@info)
33
+ QBFC::Test::Info::get(@sess)
34
+ end
35
+
36
+ it "applies options to Request" do
37
+ @request.should_receive(:apply_options).with({:owner_id => 0})
38
+ QBFC::Test::Info::get(@sess, :owner_id => 0)
39
+ end
40
+ end
41
+
42
+ describe ".find" do
43
+ it "should forward request, without 'what' argument, to get" do
44
+ QBFC::Test::Info.should_receive(:get).with(@sess, {})
45
+ QBFC::Test::Info::find(@sess, :first, {})
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe QBFC::Item do
4
+
5
+ before(:each) do
6
+ @sess = mock(QBFC::Session)
7
+ @ole_wrapper = mock(QBFC::OLEWrapper)
8
+ end
9
+
10
+ it "is a base class" do
11
+ QBFC::Item.is_base_class?.should be_true
12
+ end
13
+
14
+ describe ".find" do
15
+ it "should return subclass objects"
16
+ end
17
+
18
+ describe ".add_special" do
19
+ before(:each) do
20
+ @request = mock("QBFC::Request")
21
+ @response = mock("QBFC::Request#response")
22
+ end
23
+
24
+ it "should add a Special Account" do
25
+ QBFC::Request.should_receive(:new).with(@sess, "SpecialItemAdd").and_return(@request)
26
+ @request.should_receive(:special_item_type=).with(QBFC_CONST::SitFinanceCharge)
27
+ @request.should_receive(:response).and_return(@response)
28
+
29
+ QBFC::Item.add_special(@sess, QBFC_CONST::SitFinanceCharge)
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe "QBFC::Item generated.rb" do
4
+
5
+ it "should generate classes" do
6
+ QBFC::ItemGroup.superclass.should be(QBFC::Item)
7
+ QBFC::ItemDiscount.superclass.should be(QBFC::Item)
8
+ QBFC::ItemPayment.superclass.should be(QBFC::Item)
9
+ end
10
+
11
+ it "should include Modifiable in all classes" do
12
+ QBFC::ItemGroup.included_modules.should include(QBFC::Modifiable)
13
+ QBFC::ItemDiscount.included_modules.should include(QBFC::Modifiable)
14
+ QBFC::ItemPayment.included_modules.should include(QBFC::Modifiable)
15
+ end
16
+ end