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,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe "QBFC::Company" do
4
+
5
+ before(:each) do
6
+ @integration = QBFC::Integration::reader
7
+ @sess = @integration.session
8
+ @company = @sess.company
9
+ end
10
+
11
+ after(:each) do
12
+ @integration.close
13
+ end
14
+
15
+ it "should get name" do
16
+ @company.company_name.should == "Test Company"
17
+ end
18
+
19
+ it "should get address" do
20
+ @company.address.addr1.should == "123 Address St"
21
+ @company.address.city.should == "Oklahoma City"
22
+ @company.address.state.should == "OK"
23
+ @company.address.postal_code.should == "73160"
24
+ end
25
+
26
+ it "should get phone" do
27
+ @company.phone.should == "(555) 555-1212"
28
+ end
29
+
30
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ # This spec describes use of the :conditions option to Element.find
4
+ # The implementation that this tests is Request#apply_options
5
+
6
+ describe "conditions: " do
7
+
8
+ before(:each) do
9
+ @integration = QBFC::Integration::reader
10
+ @sess = @integration.session
11
+ end
12
+
13
+ after(:each) do
14
+ @integration.close
15
+ end
16
+
17
+ describe "Check" do
18
+ it "should limit records returned" do
19
+ checks = @sess.checks.find(:all, :limit => 2)
20
+ checks.length.should == 2
21
+ end
22
+
23
+ it "should filter on date range" do
24
+ @sess.checks.find(:all, :conditions => {:txn_date_range => '2008-02-23'..'2008-02-25'}).length.should == 1
25
+ @sess.checks.find(:all, :conditions => {:txn_date_range => '2008-02-26'}).length.should == 3
26
+ @sess.checks.find(:all, :conditions => {:txn_date_range => Date.parse('2008-02-26')}).length.should == 3
27
+ end
28
+
29
+ it "should filter on modified time" do
30
+ @sess.checks.find(:all, :conditions => {:modified_date_range => '2008-02-23'..'2008-02-25'}).length.should == 1
31
+ @sess.checks.find(:all, :conditions => {:modified_date_range => '2008-02-26'}).length.should == 3
32
+ @sess.checks.find(:all, :conditions => {:modified_date_range => Date.parse('2008-02-26')}).length.should == 3
33
+ end
34
+
35
+ it "should filter on ref number criteria" do
36
+ checks = @sess.checks.find(:all, :conditions => {:ref_number_list => %w{1000 1002}})
37
+ checks.length.should == 2
38
+ checks[0].ref_number.should == '1000'
39
+ checks[1].ref_number.should == '1002'
40
+ end
41
+
42
+ it "should filter on ref number range" do
43
+ @sess.checks.find(:all, :conditions => {:ref_number_range => '1000'..'1001'}).length.should == 2
44
+ @sess.checks.find(:all, :conditions => {:ref_number_range => 1000..1001}).length.should == 2
45
+ @sess.checks.find(:all, :conditions => {:ref_number_range => '1003'}).length.should >= 1
46
+ end
47
+
48
+ it "should filter on Entity" do
49
+ @sess.checks.find(:all, :conditions => {:entity => 'ABC Supplies'}).length.should >= 2
50
+ @sess.checks.find(:first, :conditions => {:entity => 'Computer Shop'}).ref_number.should == '1002'
51
+ end
52
+
53
+ it "should filter on Account" do
54
+ @sess.checks.find(:all, :conditions => {:account => 'Checking'}).length.should >= 4
55
+ @sess.checks.find(:all, :conditions => {:account => 'Accounts Receivable'}).length.should == 0
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe "QBFC::Customer" do
4
+
5
+ before(:each) do
6
+ @integration = QBFC::Integration::reader
7
+ @sess = @integration.session
8
+ @bob = @sess.customers.find_by_name("Bob Customer")
9
+ @sue = @sess.customers.find_by_name("Sue Customer")
10
+ end
11
+
12
+ after(:each) do
13
+ @integration.close
14
+ end
15
+
16
+ it "should get name" do
17
+ @bob.name.should == "Bob Customer"
18
+ @sue.name.should == "Sue Customer"
19
+
20
+ @bob.full_name.should == "Bob Customer"
21
+ @sue.full_name.should == "Sue Customer"
22
+ end
23
+
24
+ end
25
+
26
+ describe "QBFC::Customer(setters)" do
27
+
28
+ before(:each) do
29
+ @integration = QBFC::Integration.new
30
+ @sess = @integration.session
31
+ @bob = @sess.customers.find_by_name("Bob Customer")
32
+ end
33
+
34
+ after(:each) do
35
+ @integration.close
36
+ end
37
+
38
+ it "should set name" do
39
+ new_name = "New Customer"
40
+ @bob.name = new_name
41
+ @bob.name.should == new_name
42
+ @bob.save
43
+
44
+ @sess.customers.find(new_name).name.should == new_name
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "QBFC::Element(finders)" do
4
+
5
+ before(:each) do
6
+ @integration = QBFC::Integration::reader
7
+ @sess = @integration.session
8
+ end
9
+
10
+ after(:each) do
11
+ @integration.close
12
+ end
13
+
14
+ it "should return a subclass of a base_class (e.g. Entity)" do
15
+ entity = QBFC::Entity.find(@sess, "Bob Customer")
16
+ entity.should be_kind_of(QBFC::Customer)
17
+ entity.name.should == "Bob Customer"
18
+ end
19
+
20
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ # This spec describes use of the :conditions option to Element.find
4
+ # The implementation that this tests is Request#apply_options
5
+
6
+ def run_test
7
+ @sess.report('ProfitAndLossStandard',
8
+ :conditions => {
9
+ :report_date_range => [Date.parse("2007-08-01"), Date.parse("2007-08-31")]},
10
+ :report_basis => QBFC_CONST::RbAccrual)
11
+ end
12
+
13
+ # Setup
14
+ use_open = true
15
+
16
+ if use_open
17
+ @sess = QBFC::Session.new
18
+ else
19
+ @integration = QBFC::Integration::reader
20
+ @sess = @integration.session
21
+ end
22
+
23
+ begin
24
+ puts run_test
25
+ ensure
26
+ if use_open
27
+ @sess.close
28
+ else
29
+ @integration.close
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ # This spec describes use of the options to Element.find
4
+ # (except :conditions, which is in conditions_spec.rb)
5
+ # The implementation that this tests is Request#apply_options
6
+
7
+ describe "Request options: " do
8
+
9
+ before(:each) do
10
+ @integration = QBFC::Integration::reader
11
+ @sess = @integration.session
12
+ end
13
+
14
+ after(:each) do
15
+ @integration.close
16
+ end
17
+
18
+ describe "Invoice" do
19
+ def assert_line_items(inv)
20
+ inv.ORInvoiceLineRetList[0].InvoiceLineRet.desc == "First Line"
21
+ inv.ORInvoiceLineRetList[1].InvoiceLineRet.desc == "Second Line"
22
+ inv.ORInvoiceLineRetList[2].InvoiceLineRet.desc == "3rd Line"
23
+ end
24
+
25
+ def assert_linked_txns(inv)
26
+ inv.LinkedTxnList[0].ref_number.should == '1972'
27
+ inv.LinkedTxnList[0].amount.should == -300.00
28
+ end
29
+
30
+ it "should include line items" do
31
+ inv = @sess.invoices.find_by_ref('2', :include => [:line_items])
32
+ assert_line_items(inv)
33
+ end
34
+
35
+ it "should include linked txns" do
36
+ inv = @sess.invoices.find_by_ref('2', :include => [:linked_txns])
37
+ assert_linked_txns(inv)
38
+ end
39
+
40
+ it "should include include all (line items and linked txns)" do
41
+ inv = @sess.invoices.find_by_ref('2', :include => [:all])
42
+ assert_line_items(inv)
43
+ assert_linked_txns(inv)
44
+ end
45
+
46
+ it "should include a subset of elements" do
47
+ inv = @sess.invoices.find_by_ref('2',
48
+ :include => [:txn_id, :customer_ref, :bill_address])
49
+ inv.txn_id.should_not be_nil
50
+ inv.customer_ref.full_name.should_not be_nil
51
+ inv.bill_address.addr1.should_not be_nil
52
+
53
+ inv.ref_number.should be_nil
54
+ inv.class_ref.should be_nil
55
+ inv.bill_address_block.should be_nil
56
+ end
57
+
58
+ it "should only txn_id" do
59
+ inv = @sess.invoices.find_by_ref('2',
60
+ :include => [:txn_id])
61
+ inv.txn_id.should_not be_nil
62
+
63
+ inv.customer_ref.should be_nil
64
+ inv.bill_address.should be_nil
65
+ end
66
+ end
67
+
68
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1 @@
1
+ --exclude "spec/*,gems/*"
data/spec/spec.opts ADDED
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'qbfc'
4
+
5
+ Spec::Runner.configure do |config|
6
+
7
+ end
8
+
9
+ module QBFC
10
+ class Integration
11
+ FIXTURE_DIRNAME = File.dirname(__FILE__) + "\\fixtures"
12
+ FIXTURE_FILENAME = FIXTURE_DIRNAME + "\\test.qbw"
13
+ TMP_DIRNAME = File.dirname(__FILE__) + "\\tmp"
14
+
15
+ class << self
16
+ def reader
17
+ @@reader ||= new(true)
18
+ @@reader.open_sess
19
+ @@reader
20
+ end
21
+ end
22
+
23
+ def initialize(is_reader = false)
24
+ FileUtils.mkdir_p(TMP_DIRNAME)
25
+
26
+ @is_reader = is_reader
27
+ @@i ||= 0
28
+ @@i += 1
29
+ @dirname = TMP_DIRNAME + "\\fixture_#{@@i}"
30
+ FileUtils.rm_rf(@dirname)
31
+ FileUtils.mkdir_p(@dirname)
32
+
33
+ ['lgb', 'qbw', 'qbw.ND', 'qbw.TLG'].each do |ext|
34
+ FileUtils.cp FIXTURE_DIRNAME + "\\test.#{ext}", @dirname
35
+ end
36
+
37
+ open_sess
38
+ end
39
+
40
+ def filename
41
+ File.expand_path(@dirname + "\\test.qbw").gsub(/\//, "\\")
42
+ end
43
+
44
+ def open_sess
45
+ @sess = QBFC::Session.new(:filename => filename)
46
+ end
47
+
48
+ def session
49
+ @sess
50
+ end
51
+
52
+ def close
53
+ @sess.close
54
+ sleep(1)
55
+ unless @is_reader
56
+ sleep(3)
57
+ FileUtils.rm_rf(@dirname)
58
+ end
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe QBFC::Base do
4
+
5
+ before(:each) do
6
+ @sess = mock(QBFC::Session)
7
+ @ole_wrapper = mock(QBFC::OLEWrapper)
8
+ @ole_methods = ["FullName", "ListID"]
9
+ @base = QBFC::Base.new(@sess, @ole_wrapper)
10
+ end
11
+
12
+ it "requires a QBFC:Session argument" do
13
+ lambda {QBFC::Base.new()}.should raise_error
14
+ lambda {QBFC::Base.new(@sess)}.should_not raise_error
15
+ end
16
+
17
+ it "initializes with an optional ole_object argument" do
18
+ lambda {QBFC::Base.new(@sess, @ole_wrapper)}.should_not raise_error
19
+ end
20
+
21
+ it "should wrap (only) a WIN32OLE object in an OLEWrapper" do
22
+ @ole_object = mock(WIN32OLE)
23
+ @ole_object.should_receive(:kind_of?).with(WIN32OLE).and_return(true)
24
+ QBFC::OLEWrapper.should_receive(:new).with(@ole_object).and_return(@ole_wrapper)
25
+
26
+ QBFC::Base.new(@sess, @ole_object)
27
+ end
28
+
29
+ it "should not wrap non-WIN32OLE objects" do
30
+ @ole_wrapper.should_receive(:kind_of?).with(WIN32OLE).and_return(false)
31
+ QBFC::OLEWrapper.should_not_receive(:new).with(@ole_object)
32
+
33
+ QBFC::Base.new(@sess, @ole_wrapper)
34
+ end
35
+
36
+ it "lists OLE methods for OLEWrapper object" do
37
+ @ole_wrapper.should_receive(:ole_methods).and_return(@ole_methods)
38
+ @base.ole_methods.should be(@ole_methods)
39
+ end
40
+
41
+ it "has a respond_to_ole? method" do
42
+ @ole_wrapper.should_receive(:respond_to_ole?).with("FullName").and_return(true)
43
+ @base.respond_to_ole?("FullName").should be_true
44
+
45
+ @ole_wrapper.should_receive(:respond_to_ole?).with("NoMethod").and_return(false)
46
+ @base.respond_to_ole?("NoMethod").should be_false
47
+ end
48
+
49
+ it "should pass unknown method calls to OLEWrapper#qbfc_method_missing" do
50
+ @ole_wrapper.should_receive(:qbfc_method_missing).with(@sess, :full_name=, "arg")
51
+ @base.full_name = "arg"
52
+ end
53
+
54
+ it "has a qb_name class method" do
55
+ QBFC::Base.qb_name.should == "Base"
56
+ end
57
+
58
+ it "aliases qb_name class method as an instance method" do
59
+ @base.qb_name.should == QBFC::Base.qb_name
60
+ end
61
+
62
+ it "should create_query" do
63
+ QBFC::Request.should_receive(:new).with(@sess, "BaseQuery")
64
+ QBFC::Base.__send__(:create_query, @sess)
65
+ end
66
+
67
+ it "should should respond to is_base_class? with false" do
68
+ QBFC::Base.is_base_class?.should be_false
69
+ end
70
+
71
+ describe ".parse_find_args" do
72
+ before(:each) do
73
+ @options = {:include_items => true, :owner_id => 0, :conditions => {}}
74
+ end
75
+
76
+ it "should return a Request object if given one" do
77
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request, @options)
78
+ rq.should be(@request)
79
+
80
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request)
81
+ rq.should be(@request)
82
+ end
83
+
84
+ it "should return nil request if no Request given" do
85
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
86
+ rq.should be_nil
87
+
88
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args)
89
+ rq.should be_nil
90
+ end
91
+
92
+ it "should return dup of options if given them" do
93
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request, @options)
94
+ opt.should == @options
95
+
96
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
97
+ opt.should == @options
98
+ end
99
+
100
+ it "should return an empty hash for options if not given them" do
101
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request)
102
+ opt.should == {}
103
+
104
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args)
105
+ opt.should == {}
106
+ end
107
+
108
+ it "should return base_options if is_base_class?" do
109
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, {})
110
+ base_opt.should == {}
111
+ end
112
+
113
+ it "should make base_options and options separate objects" do
114
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
115
+ base_opt.should_not be(opt)
116
+ end
117
+
118
+ it "should return nil for base_options if isn't a base class" do
119
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, {})
120
+ base_opt.should be_nil
121
+ end
122
+
123
+ it "should delete :conditions from base_options" do
124
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
125
+ base_opt.should == {:include_items => true, :owner_id => 0}
126
+ end
127
+
128
+ it "should delete :owner_id from options if a base class" do
129
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
130
+ opt.should == {:include_items => true, :conditions => {}}
131
+ end
132
+
133
+ it "should not delete :owner_id if not a base class" do
134
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
135
+ opt.should == {:include_items => true, :owner_id => 0, :conditions => {}}
136
+ end
137
+ end
138
+ end