qbfc 0.1.0-x86-mswin32-60
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/MIT-LICENSE +20 -0
- data/README +41 -0
- data/Rakefile +82 -0
- data/lib/qbfc.rb +39 -0
- data/lib/qbfc/base.rb +82 -0
- data/lib/qbfc/element.rb +178 -0
- data/lib/qbfc/entities/generated.rb +8 -0
- data/lib/qbfc/entity.rb +11 -0
- data/lib/qbfc/info.rb +42 -0
- data/lib/qbfc/infos/generated.rb +9 -0
- data/lib/qbfc/item.rb +10 -0
- data/lib/qbfc/items/generated.rb +11 -0
- data/lib/qbfc/list.rb +84 -0
- data/lib/qbfc/lists/generated.rb +15 -0
- data/lib/qbfc/lists/qb_class.rb +25 -0
- data/lib/qbfc/modifiable.rb +31 -0
- data/lib/qbfc/ole_wrapper.rb +193 -0
- data/lib/qbfc/qb_collection.rb +26 -0
- data/lib/qbfc/qb_types.rb +34 -0
- data/lib/qbfc/qbfc_const.rb +14 -0
- data/lib/qbfc/request.rb +158 -0
- data/lib/qbfc/session.rb +136 -0
- data/lib/qbfc/terms.rb +10 -0
- data/lib/qbfc/terms/generated.rb +10 -0
- data/lib/qbfc/transaction.rb +83 -0
- data/lib/qbfc/transactions/generated.rb +18 -0
- data/lib/qbfc/voidable.rb +11 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +62 -0
- data/spec/unit/base_spec.rb +138 -0
- data/spec/unit/element_finder_spec.rb +180 -0
- data/spec/unit/element_spec.rb +118 -0
- data/spec/unit/entities/generated_spec.rb +18 -0
- data/spec/unit/entity_spec.rb +18 -0
- data/spec/unit/info/generated_spec.rb +12 -0
- data/spec/unit/info_spec.rb +48 -0
- data/spec/unit/item_spec.rb +18 -0
- data/spec/unit/items/generated_spec.rb +16 -0
- data/spec/unit/list_finders_spec.rb +128 -0
- data/spec/unit/list_spec.rb +86 -0
- data/spec/unit/lists/generated_spec.rb +15 -0
- data/spec/unit/lists/qb_class_spec.rb +9 -0
- data/spec/unit/modifiable_spec.rb +84 -0
- data/spec/unit/ole_wrapper_spec.rb +293 -0
- data/spec/unit/qb_collection_spec.rb +13 -0
- data/spec/unit/qbfc_const_spec.rb +10 -0
- data/spec/unit/qbfc_spec.rb +10 -0
- data/spec/unit/request_query_survey.txt +48 -0
- data/spec/unit/request_spec.rb +236 -0
- data/spec/unit/session_spec.rb +138 -0
- data/spec/unit/terms/generated_spec.rb +14 -0
- data/spec/unit/terms_spec.rb +18 -0
- data/spec/unit/transaction_finders_spec.rb +124 -0
- data/spec/unit/transaction_spec.rb +94 -0
- data/spec/unit/transactions/generated_spec.rb +20 -0
- data/spec/unit/voidable_spec.rb +32 -0
- metadata +140 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
module QBFC
|
2
|
+
|
3
|
+
# A QBCollection object is used as an intermediate object when doing finds,
|
4
|
+
# for example, in <tt>qb_session.customers.find(:all)</tt>, +customers+
|
5
|
+
# returns a QBCollection instance which then is sent the find call.
|
6
|
+
# The instance sends the find method on to the appropriate Class.
|
7
|
+
# The reason for having this intermediate class is to be able to
|
8
|
+
# pass a reference to the Session to the find method
|
9
|
+
# (or other class method).
|
10
|
+
#
|
11
|
+
# There's probably no reason to use this class directly.
|
12
|
+
class QBCollection
|
13
|
+
|
14
|
+
# +sess+ is a QBFC::Session object, +class_name+ is the name of
|
15
|
+
# a class descended from QBFC::Base.
|
16
|
+
def initialize(sess, class_name)
|
17
|
+
@sess = sess
|
18
|
+
@klass = QBFC::const_get(class_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Send any missing methods to the class, along with the +Session+ object
|
22
|
+
def method_missing(symbol, *params) #:nodoc:
|
23
|
+
@klass.send(symbol, @sess, *params)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# This file sets up the classes for QuickBooks entities, transactions and reports.
|
2
|
+
|
3
|
+
# Types that allow Query and Delete only
|
4
|
+
QBFC_DELETE_ONLY = %w{PayrollItemNonWage DataEventRecoveryInfo}
|
5
|
+
|
6
|
+
# Report types return an IReportRet
|
7
|
+
QBFC_REPORT_TYPES = %w{AgingReport BudgetSummaryReport CustomDetailReport CustomSummaryReport
|
8
|
+
GeneralDetailReport GeneralSummaryReport JobReport PayrollDetailReport PayrollSummaryReport TimeReport }
|
9
|
+
|
10
|
+
# Types that allow Special adds (Pre-defined and normally added automatically by QuickBooks)
|
11
|
+
QBFC_HAS_SPECIAL_ADD = %w{Account Item}
|
12
|
+
|
13
|
+
# TODO: Here and below arrays I haven't yet formed any approach to dealing with.
|
14
|
+
# I leave them here as a reminder.
|
15
|
+
ELEMENTS_ADD_MOD = %w{ DataExt }
|
16
|
+
|
17
|
+
ELEMENTS_ADD_MOD_QUERY = %w{ DataExtDef }
|
18
|
+
|
19
|
+
# Types that have their own DelRq
|
20
|
+
ELEMENT_DEL_TYPES = %w{DataEventRecoveryInfo DataExt DataExtDef}
|
21
|
+
|
22
|
+
# Query types support Query requests only and return an itemized list of some sort;
|
23
|
+
# most of these may be integrated as special finders for their types.
|
24
|
+
QBFC_QUERY_TYPES = %w{BillToPay ListDeleted ReceivePaymentToDeposit Template TxnDeleted SalesTaxPaymentCheck}
|
25
|
+
|
26
|
+
QBFC_ANOTHER_TO_INTEGRATE_SOMEWHERE = %w{ ItemAssembliesCanBuild }
|
27
|
+
|
28
|
+
|
29
|
+
module QBFC
|
30
|
+
# Create QBElement classes
|
31
|
+
(QBFC_REPORT_TYPES + QBFC_DELETE_ONLY + %w{DataExt DataExtDef}).uniq.each do | qb_element_name |
|
32
|
+
const_set(qb_element_name, Class.new(Base))
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# QBFC_CONST contains constants defined by QBFC6.QBSessionManager.
|
2
|
+
# For example:
|
3
|
+
#
|
4
|
+
# QBFC_CONST::DmToday # => 1 (for DateMacro)
|
5
|
+
#
|
6
|
+
# The constants defined in the SDK documents all begin with a lower case letter.
|
7
|
+
# In contrast, WIN32OLE capitalizes the constants to follow Ruby naming conventions:
|
8
|
+
#
|
9
|
+
# QBFC_CONST::DmToday instead of QBFC_CONST::dmToday
|
10
|
+
|
11
|
+
module QBFC_CONST
|
12
|
+
end
|
13
|
+
|
14
|
+
WIN32OLE.const_load(WIN32OLE.new('QBFC6.QBSessionManager'), QBFC_CONST)
|
data/lib/qbfc/request.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
module QBFC
|
2
|
+
# A QBFC::Request handles creating and sending a Request, including creating
|
3
|
+
# the RequestSet. Most often, RubyQBFC classes create and execute the Request
|
4
|
+
# internally, however, the Base.find, for example, accepts a QBFC::Request
|
5
|
+
# object as an argument if greater control is needed.
|
6
|
+
#
|
7
|
+
# The WIN32OLE Request object is wrapped in OLEWrapper, so Ruby-esque methods
|
8
|
+
# can be used.
|
9
|
+
#
|
10
|
+
# req = QBFC::Request.new(qb_session, "CustomerQuery").
|
11
|
+
# or_customer_list_query.customer_list_filter.max_returned = 2
|
12
|
+
# puts req.response
|
13
|
+
class Request
|
14
|
+
|
15
|
+
# <tt>session</tt> is a QBFC::Session object (or a Session object not created through Ruby QBFC)
|
16
|
+
# <tt>request_type</tt> is the name of the request, not including trailing 'Rq',
|
17
|
+
# e.g. 'CustomerQuery', 'CustomerMod'
|
18
|
+
def initialize(sess, request_type, country = 'US', major_version = 6, minor_version = 0)
|
19
|
+
@sess = sess
|
20
|
+
|
21
|
+
begin
|
22
|
+
@request_set = sess.CreateMsgSetRequest(country, major_version, minor_version)
|
23
|
+
rescue WIN32OLERuntimeError => error
|
24
|
+
if error.to_s =~ /error code:8004030A/
|
25
|
+
raise QBFC::QBXMLVersionError, "Unsupported qbXML version"
|
26
|
+
else
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
@request = @request_set.send("Append#{request_type}Rq")
|
33
|
+
rescue WIN32OLERuntimeError => error
|
34
|
+
if error.to_s =~ /error code:0x80020006/
|
35
|
+
raise QBFC::UnknownRequestError, "Unknown request name '#{request_type}'"
|
36
|
+
else
|
37
|
+
raise
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Submit the requests. This returns the full (not wrapped) response object.
|
43
|
+
def submit
|
44
|
+
@sess.DoRequests(@request_set)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Submit the Request and return the response Detail, wrapped in OLEWrapper (unless nil).
|
48
|
+
# The response does not include any MsgSetResponse attributes.
|
49
|
+
def response
|
50
|
+
submit.ResponseList.GetAt(0).Detail
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the OR*Query object of the given Request
|
54
|
+
# For example, the ORListQuery
|
55
|
+
def query
|
56
|
+
query_name = @request.ole_methods.detect{|m| m.to_s =~ /Query\Z/}
|
57
|
+
return nil if query_name.nil?
|
58
|
+
@request.send(query_name.to_s.to_sym)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get the *Filter object of the given Request
|
62
|
+
# For example, the ListFilter
|
63
|
+
def filter
|
64
|
+
q = self.query
|
65
|
+
return nil if q.nil?
|
66
|
+
filter_name = q.ole_methods.detect{|m| m.to_s =~ /Filter\Z/}
|
67
|
+
return nil if filter_name.nil?
|
68
|
+
q.send(filter_name.to_s.to_sym)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns where the filter is available for use. That is, that
|
72
|
+
# none of the query options other than filter have been used
|
73
|
+
def filter_available?
|
74
|
+
# -1 = unused, 2 = Filter used
|
75
|
+
self.query.ole_object.ortype == -1 ||
|
76
|
+
self.query.ole_object.ortype == 2
|
77
|
+
end
|
78
|
+
|
79
|
+
# Applies options from a Hash. This method is primarily experimental
|
80
|
+
# (and proof of concept) at this time.
|
81
|
+
def apply_options(options)
|
82
|
+
if options.kind_of? Hash
|
83
|
+
filters = options[:conditions]
|
84
|
+
if filters
|
85
|
+
if filters[:txn_date]
|
86
|
+
txn_date_filter = q.ORTxnQuery.TxnFilter.ORDateRangeFilter.TxnDateRangeFilter.ORTxnDateRangeFilter.TxnDateFilter
|
87
|
+
txn_date_filter.FromTxnDate.SetValue( filters[:txn_date][0] ) if filters[:txn_date][0]
|
88
|
+
txn_date_filter.ToTxnDate.SetValue( filters[:txn_date][1] ) if filters[:txn_date][1]
|
89
|
+
filters.delete(:txn_date)
|
90
|
+
end
|
91
|
+
|
92
|
+
if filters[:ref_number]
|
93
|
+
ref_num_filter = q.send("OR#{self.qb_name}Query").send("#{self.qb_name}Filter").
|
94
|
+
ORRefNumberFilter.RefNumberRangeFilter
|
95
|
+
ref_num_filter.FromRefNumber.SetValue( filters[:ref_number][0] ) if filters[:ref_number][0]
|
96
|
+
ref_num_filter.ToRefNumber.SetValue( filters[:ref_number][1] ) if filters[:ref_number][1]
|
97
|
+
filters.delete(:ref_number)
|
98
|
+
end
|
99
|
+
|
100
|
+
filters.each do |filter, value|
|
101
|
+
q.send("OR#{self.qb_name}Query").
|
102
|
+
send("#{self.qb_name}Filter").
|
103
|
+
send("#{filter}=", QBFC_CONST::PsNotPaidOnly)
|
104
|
+
end
|
105
|
+
|
106
|
+
options.delete(:conditions)
|
107
|
+
end
|
108
|
+
|
109
|
+
add_owner_ids(options.delete(:owner_id))
|
110
|
+
|
111
|
+
options.each do |key, value|
|
112
|
+
q.send(key.to_s.camelize).SetValue(value)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
# Add one or more OwnerIDs to the Request. Used in retrieving
|
119
|
+
# custom fields (aka private data extensions).
|
120
|
+
# Argument should be a single ID or an Array of IDs.
|
121
|
+
def add_owner_ids(ids)
|
122
|
+
return if ids.nil?
|
123
|
+
|
124
|
+
ids = [ids] unless ids.respond_to?(:each)
|
125
|
+
ids.each do | id |
|
126
|
+
@request.OwnerIDList.Add(id)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Send missing methods to @ole_object (OLEWrapper)
|
131
|
+
def method_missing(symbol, *params) #:nodoc:
|
132
|
+
@request.qbfc_method_missing(@sess, symbol, *params)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Return Array of ole_methods for request WIN32OLE object.
|
136
|
+
# This is mostly useful for debugging.
|
137
|
+
def ole_methods
|
138
|
+
@request.ole_methods
|
139
|
+
end
|
140
|
+
|
141
|
+
# Return XML for the request WIN32OLE object.
|
142
|
+
# This is mostly useful for debugging.
|
143
|
+
def to_xml
|
144
|
+
@request_set.ToXMLString
|
145
|
+
end
|
146
|
+
|
147
|
+
# Submit Request and return full response as XML.
|
148
|
+
# This is mostly useful for debugging.
|
149
|
+
def response_xml
|
150
|
+
@sess.DoRequests(@request_set).ToXMLString
|
151
|
+
end
|
152
|
+
|
153
|
+
# Return actual WIN32OLE object
|
154
|
+
def ole_object
|
155
|
+
@request.ole_object
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/qbfc/session.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
module QBFC
|
2
|
+
class QuickbooksClosedError < RuntimeError #:nodoc:
|
3
|
+
end
|
4
|
+
class SetValueMissing < RuntimeError#:nodoc:
|
5
|
+
end
|
6
|
+
class QBXMLVersionError < RuntimeError#:nodoc:
|
7
|
+
end
|
8
|
+
class UnknownRequestError < RuntimeError#:nodoc:
|
9
|
+
end
|
10
|
+
class BaseClassNewError < RuntimeError#:nodoc:
|
11
|
+
end
|
12
|
+
class NotSavableError < RuntimeError#:nodoc:
|
13
|
+
end
|
14
|
+
|
15
|
+
# Encapsulates a QBFC session.
|
16
|
+
#
|
17
|
+
# QBFC::Session.open(:app_name => 'Test Application') do |qb|
|
18
|
+
# qb.customers.find(:all).each do |customer|
|
19
|
+
# puts customer.full_name
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# qb = QBFC::Session.new(:app_name => 'Test Application')
|
24
|
+
# qb.customers.find(:all).each do |customer|
|
25
|
+
# puts customer.full_name
|
26
|
+
# end
|
27
|
+
# qb.close
|
28
|
+
#
|
29
|
+
# A QBFC::Session abstracts the ole_methods so that more conventional Ruby method names are used,
|
30
|
+
# e.g. <tt>full_name</tt> instead of <tt>FullName.GetValue()</tt>.
|
31
|
+
#
|
32
|
+
# This also allows a shortcut for setting up Quickbooks objects:
|
33
|
+
#
|
34
|
+
# - session.customers.find(:all) instead of QBFC::Customer.find(session, :all)
|
35
|
+
# - session.customer('CustomerFullName') instead of QBFC::Customer.find(session, 'CustomerFullName')
|
36
|
+
# - session.customer instead of QBFC::Customer.find(session, :first)
|
37
|
+
class Session
|
38
|
+
class << self
|
39
|
+
|
40
|
+
# Open a QBFC session. Takes options as a hash, and an optional block. Options are:
|
41
|
+
#
|
42
|
+
# - +app_name+: Name that the application sends to Quickbooks (used for allowing/denying access)
|
43
|
+
# (defaults to 'Ruby QBFC Application'
|
44
|
+
# - +app_id+: Per the Quickbooks SDK (QBFC Language Reference):
|
45
|
+
# 'Normally not assigned. Use an empty string for appID.' An empty string is passed by default.
|
46
|
+
# - +conn_type+: QBFC_CONST::CtUnknown, CtLocalQBD, CtRemoteQBD, CtLocalQBDLaunchUI, or CtRemoteQBOE.
|
47
|
+
# Default is QBFC_CONST::CtLocalQBD (1)
|
48
|
+
# - +filename+: The full path to the Quickbooks file; leave blank to connect to the currently
|
49
|
+
# open company file. Default is an empty string (Quickbooks should be running).
|
50
|
+
# - +open_mode+: The desired access mode. It can be one of three values:
|
51
|
+
# - QBFC_CONST::OmSingleUser (specifies single-user mode)
|
52
|
+
# - QBFC_CONST::OmMultiUser (specifies multi-user mode)
|
53
|
+
# - QBFC_CONST::OmDontCare (accept whatever mode is currently in effect, or single-user mode if no other mode is in effect)
|
54
|
+
# Default is QBFC_CONST::OmDontCare
|
55
|
+
#
|
56
|
+
# If given a block, it yields the Session object and closes the Session and Connection
|
57
|
+
# when the block closes.
|
58
|
+
#
|
59
|
+
# Otherwise, it returns the new Session object.
|
60
|
+
|
61
|
+
def open(*options, &block)
|
62
|
+
qb = new(*options)
|
63
|
+
if block_given?
|
64
|
+
begin
|
65
|
+
yield qb
|
66
|
+
ensure
|
67
|
+
qb.close
|
68
|
+
end
|
69
|
+
else
|
70
|
+
qb
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
# See Session.open for initialization options.
|
77
|
+
def initialize(options = {})
|
78
|
+
ole_object = WIN32OLE.new("QBFC6.QBSessionManager")
|
79
|
+
|
80
|
+
ole_object.OpenConnection2(options[:app_id].to_s,
|
81
|
+
(options[:app_name] || "Ruby QBFC Application"),
|
82
|
+
(options[:conn_type] || QBFC_CONST::CtLocalQBD))
|
83
|
+
|
84
|
+
begin
|
85
|
+
ole_object.BeginSession(options[:filename].to_s,
|
86
|
+
(options[:open_mode] || QBFC_CONST::OmDontCare))
|
87
|
+
rescue WIN32OLERuntimeError
|
88
|
+
ole_object.CloseConnection
|
89
|
+
ole_object = nil
|
90
|
+
raise QBFC::QuickbooksClosedError, "BeginSession failed: Quickbooks must be open or a valid filename specified."
|
91
|
+
end
|
92
|
+
|
93
|
+
@ole_object = QBFC::OLEWrapper.new(ole_object)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Close the session with Quickbooks. If this is ommitted, Quickbooks will not close.
|
97
|
+
# Using a block with Session.open ensures the session is closed.
|
98
|
+
def close
|
99
|
+
@ole_object.EndSession
|
100
|
+
@ole_object.CloseConnection
|
101
|
+
@ole_object = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
# The classes method allows using <tt>session.classes.find</tt> instead of
|
105
|
+
# <tt>session.q_b_classes.find</tt>, for finds on QBClass.
|
106
|
+
def classes
|
107
|
+
QBFC::QBCollection.new(self, :QBClass)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Responsible for the conversion of ole_method name to more convential Ruby method names.
|
111
|
+
# This specifies the methods for setting up an Entity, such as a Customer, directly, which is
|
112
|
+
# not included in OLEWrapper (setting up entities that are children of another entity is).
|
113
|
+
# Send other missing methods on to OLE Wrapper
|
114
|
+
def method_missing(symbol, *params) #:nodoc:
|
115
|
+
if (('a'..'z') === symbol.to_s[0].chr && symbol.to_s[-1].chr != '=')
|
116
|
+
camelized_method = symbol.to_s.camelize.to_sym
|
117
|
+
single_camelized_method = symbol.to_s.singularize.camelize.to_sym
|
118
|
+
if QBFC.const_defined?(camelized_method)
|
119
|
+
if params[0]
|
120
|
+
return QBFC::const_get(camelized_method).find_by_unique_id(self, params[0])
|
121
|
+
else
|
122
|
+
return QBFC::const_get(camelized_method).find(self, :first)
|
123
|
+
end
|
124
|
+
elsif QBFC.const_defined?(single_camelized_method)
|
125
|
+
return QBFC::QBCollection.new(self, single_camelized_method)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Don't want to pass an OLEWrapper to a WIN32OLE method.
|
130
|
+
params = params.collect{ |p| p.respond_to?(:ole_object) ? p.ole_object : p }
|
131
|
+
|
132
|
+
@ole_object.qbfc_method_missing(self, symbol, *params)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
data/lib/qbfc/terms.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/voidable'
|
2
|
+
|
3
|
+
module QBFC
|
4
|
+
class Transaction < Element
|
5
|
+
is_base_class
|
6
|
+
ID_NAME = "TxnID"
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Find by Reference Number of the Transaction record.
|
11
|
+
# +options+ are the same as those for in +find+.
|
12
|
+
def find_by_ref(sess, ref, options = {})
|
13
|
+
q = create_query(sess)
|
14
|
+
q.query.RefNumberList.Add(ref)
|
15
|
+
find(sess, :first, q, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Find by TxnID of List record.
|
19
|
+
# +options+ are the same as those for in +find+.
|
20
|
+
def find_by_id(sess, id, options = {})
|
21
|
+
q = create_query(sess)
|
22
|
+
q.query.TxnIDList.Add(id)
|
23
|
+
find(sess, :first, q, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Find by either ref or id. Tries id first, then ref.
|
27
|
+
def find_by_ref_or_id(*args)
|
28
|
+
find_by_id(*args) || find_by_ref(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :find_by_unique_id, :find_by_ref_or_id
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# Alias of TxnID for this record.
|
36
|
+
def id
|
37
|
+
@ole.txn_id
|
38
|
+
end
|
39
|
+
|
40
|
+
# Delete this Transaction
|
41
|
+
def delete
|
42
|
+
req = QBFC::Request.new(@sess, "TxnDel")
|
43
|
+
req.txn_del_type = QBFC_CONST::const_get("Tdt#{qb_name}")
|
44
|
+
req.txn_id = id
|
45
|
+
req.submit
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
|
49
|
+
# Change cleared status of transaction
|
50
|
+
# status can be one of:
|
51
|
+
# - QBFC::CsCleared (or true)
|
52
|
+
# - QBFC::CsNotCleared (or false)
|
53
|
+
# - QBFC::CsPending
|
54
|
+
def cleared_status=(status)
|
55
|
+
req = QBFC::Request.new(@sess, "ClearedStatusMod")
|
56
|
+
req.txn_id = id
|
57
|
+
status = QBFC_CONST::CsCleared if status === true
|
58
|
+
status = QBFC_CONST::CsNotCleared if status === false
|
59
|
+
req.cleared_status = status
|
60
|
+
req.submit
|
61
|
+
return status
|
62
|
+
end
|
63
|
+
|
64
|
+
# Display the Transaction add (for new records) or edit dialog box
|
65
|
+
def display
|
66
|
+
if new_record?
|
67
|
+
req = QBFC::Request.new(@sess, "TxnDisplayAdd")
|
68
|
+
req.txn_display_add_type = QBFC_CONST::const_get("Tdat#{qb_name}")
|
69
|
+
else
|
70
|
+
req = QBFC::Request.new(@sess, "TxnDisplayMod")
|
71
|
+
req.txn_display_mod_type = QBFC_CONST::const_get("Tdmt#{qb_name}")
|
72
|
+
req.txn_id = id
|
73
|
+
end
|
74
|
+
req.submit
|
75
|
+
return true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Require subclass files
|
81
|
+
Dir[File.dirname(__FILE__) + '/transactions/*.rb'].each do |file|
|
82
|
+
require file
|
83
|
+
end
|