module QBFC # A QBFC::Request handles creating and sending a Request, including creating # the RequestSet. Most often, RubyQBFC classes create and execute the Request # internally, however, the Base.find, for example, accepts a QBFC::Request # object as an argument if greater control is needed. # # The WIN32OLE Request object is wrapped in OLEWrapper, so Ruby-esque methods # can be used. # # req = QBFC::Request.new(qb_session, "CustomerQuery"). # or_customer_list_query.customer_list_filter.max_returned = 2 # puts req.response class Request # session is a QBFC::Session object (or a Session object not created through Ruby QBFC) # request_type is the name of the request, not including trailing 'Rq', # e.g. 'CustomerQuery', 'CustomerMod' def initialize(sess, request_type, country = 'US', major_version = 6, minor_version = 0) @sess = sess begin @request_set = sess.CreateMsgSetRequest(country, major_version, minor_version) rescue WIN32OLERuntimeError => error if error.to_s =~ /error code:8004030A/ raise QBFC::QBXMLVersionError, "Unsupported qbXML version" else raise end end begin @request = @request_set.send("Append#{request_type}Rq") rescue WIN32OLERuntimeError => error if error.to_s =~ /error code:0x80020006/ raise QBFC::UnknownRequestError, "Unknown request name '#{request_type}'" else raise end end end # Submit the requests. This returns the full (not wrapped) response object. def submit @sess.DoRequests(@request_set) end # Submit the Request and return the response Detail, wrapped in OLEWrapper (unless nil). # The response does not include any MsgSetResponse attributes. def response submit.ResponseList.GetAt(0).Detail end # Get the OR*Query object of the given Request # For example, the ORListQuery def query query_name = @request.ole_methods.detect{|m| m.to_s =~ /Query\Z/} return nil if query_name.nil? @request.send(query_name.to_s.to_sym) end # Get the *Filter object of the given Request # For example, the ListFilter def filter q = self.query return nil if q.nil? filter_name = q.ole_methods.detect{|m| m.to_s =~ /Filter\Z/} return nil if filter_name.nil? q.send(filter_name.to_s.to_sym) end # Returns where the filter is available for use. That is, that # none of the query options other than filter have been used def filter_available? # -1 = unused, 2 = Filter used self.query.ole_object.ortype == -1 || self.query.ole_object.ortype == 2 end # Applies options from a Hash. This method is primarily experimental # (and proof of concept) at this time. def apply_options(options) if options.kind_of? Hash filters = options[:conditions] if filters if filters[:txn_date] txn_date_filter = q.ORTxnQuery.TxnFilter.ORDateRangeFilter.TxnDateRangeFilter.ORTxnDateRangeFilter.TxnDateFilter txn_date_filter.FromTxnDate.SetValue( filters[:txn_date][0] ) if filters[:txn_date][0] txn_date_filter.ToTxnDate.SetValue( filters[:txn_date][1] ) if filters[:txn_date][1] filters.delete(:txn_date) end if filters[:ref_number] ref_num_filter = q.send("OR#{self.qb_name}Query").send("#{self.qb_name}Filter"). ORRefNumberFilter.RefNumberRangeFilter ref_num_filter.FromRefNumber.SetValue( filters[:ref_number][0] ) if filters[:ref_number][0] ref_num_filter.ToRefNumber.SetValue( filters[:ref_number][1] ) if filters[:ref_number][1] filters.delete(:ref_number) end filters.each do |filter, value| q.send("OR#{self.qb_name}Query"). send("#{self.qb_name}Filter"). send("#{filter}=", QBFC_CONST::PsNotPaidOnly) end options.delete(:conditions) end add_owner_ids(options.delete(:owner_id)) options.each do |key, value| q.send(key.to_s.camelize).SetValue(value) end end end # Add one or more OwnerIDs to the Request. Used in retrieving # custom fields (aka private data extensions). # Argument should be a single ID or an Array of IDs. def add_owner_ids(ids) return if ids.nil? ids = [ids] unless ids.respond_to?(:each) ids.each do | id | @request.OwnerIDList.Add(id) end end # Send missing methods to @ole_object (OLEWrapper) def method_missing(symbol, *params) #:nodoc: @request.qbfc_method_missing(@sess, symbol, *params) end # Return Array of ole_methods for request WIN32OLE object. # This is mostly useful for debugging. def ole_methods @request.ole_methods end # Return XML for the request WIN32OLE object. # This is mostly useful for debugging. def to_xml @request_set.ToXMLString end # Submit Request and return full response as XML. # This is mostly useful for debugging. def response_xml @sess.DoRequests(@request_set).ToXMLString end # Return actual WIN32OLE object def ole_object @request.ole_object end end end