Module: Quickbooks

Extended by:
Adaptability
Defined in:
lib/quickbooks/version.rb,
lib/quickbooks.rb,
lib/quickbooks/xsd.rb,
lib/quickbooks/type.rb,
lib/quickbooks/model.rb,
lib/quickbooks/types.rb,
lib/quickbooks/option.rb,
lib/quickbooks/element.rb,
lib/quickbooks/property.rb,
lib/quickbooks/ruby_ext.rb,
lib/quickbooks/xsd/group.rb,
lib/quickbooks/xsd/union.rb,
lib/quickbooks/xsd/choice.rb,
lib/quickbooks/xsd/element.rb,
lib/quickbooks/adaptability.rb,
lib/quickbooks/xsd/sequence.rb,
lib/quickbooks/xsd/attribute.rb,
lib/quickbooks/xsd/restriction.rb,
lib/quickbooks/xsd/simple_type.rb,
lib/quickbooks/xsd/complex_type.rb,
lib/quickbooks/adapters/ole_adapter.rb,
lib/quickbooks/adapters/http_adapter.rb,
lib/quickbooks/adapters/spew_adapter.rb,
lib/quickbooks/adapters/test_adapter.rb,
lib/quickbooks/adapters/https_adapter.rb

Overview

This is a fake adapter simply for testing Qbxml Requests.

Defined Under Namespace

Modules: Adaptability, Adapters, Elements, Models, Properties, Support, Types, VERSION Classes: Element, Model, Option, Options, Property, Type, XSD

Constant Summary collapse

ValidationError =
Class.new(RuntimeError)
AttributeAssignmentError =
Class.new(RuntimeError)
InvalidAttributeError =
Class.new(AttributeAssignmentError)
QuickbooksAPIError =
Class.new(RuntimeError)
HTTPConnectorError =
Class.new(RuntimeError)

Class Method Summary collapse

Methods included from Adaptability

connected?, connection, connection=, establish_connection, extended, use_adapter

Class Method Details

.execute(requestish) ⇒ Object

Execute a Request to Quickbooks and parse the answer back into QB gem objects.

Raises:

  • (RuntimeError)


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/quickbooks.rb', line 131

def execute(requestish)
  request = requestify(requestish)
  response_klass_name = request[:QBXMLMsgsRq].attributes[0].class.short_name.gsub(/Rq/, 'Rs')
  @last_response = send_request(request)
  raise RuntimeError, "Response invalid!" unless @last_response.respond_to?(:[])
  # Here, if the response we got was an error (<ConnectorError><ErrorMessage>...</ErrorMessage></ConnectorError>), deal with it now.
  raise HTTPConnectorError, @last_response[:ConnectorError][:ErrorMessage] if @last_response[:ConnectorError]
  raise RuntimeError, "Response did not include QBXMLMsgsRs." unless @last_response[:QBXMLMsgsRs]
  raise RuntimeError, "Response not the right type (#{response_klass_name})." unless @last_response[:QBXMLMsgsRs][response_klass_name]
  # raise RuntimeError, "Response has no results." unless @last_response[:QBXMLMsgsRs][response_klass_name][0].nil?
  rs = @last_response[:QBXMLMsgsRs][response_klass_name][0]
  if rs && rs['statusSeverity'] == 'Error'
    raise QuickbooksAPIError, "##{rs['statusCode']}: #{rs['statusMessage']}"
  end
  @last_response
end

.get_constant(const) ⇒ Object

Quickbooks.get_constant. See QB.



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/quickbooks.rb', line 98

def get_constant(const)
  const = const.to_s
  return loaded_classes[const] if loaded_classes.has_key?(const)
  # TODO: Need to auto-generate Models too!
  # If const+'Ret' exists, generate a Model class for const.
  if const_xsd = xsd(true)[const] || xsd(true)[const+'Ret'] || xsd(true)[const+'Add'] || xsd(true)[const+'Mod']
    loaded_classes[const] = const_xsd.to_class(const)
  else
    raise RuntimeError, "The Quickbooks class '#{const}' could not be found (called from #{caller[1]}) in QBXML Version #{qbxml_version}. Please report to [email protected] if you think this is a BUG! (#{xsd.inspect} : #{const.inspect} => #{xsd[const]})"
  end
end

.loaded_classesObject



148
149
150
151
# File 'lib/quickbooks.rb', line 148

def loaded_classes
  @loaded_classes ||= {}
  @loaded_classes[qbxml_version(true)] ||= {}
end

.qbxml(&block) ⇒ Object

Raises:

  • (ArgumentError)


125
126
127
128
# File 'lib/quickbooks.rb', line 125

def qbxml(&block)
  raise ArgumentError unless block_given?
  yield
end

.qbxml_version(autoload = false) ⇒ Object

Set or retrieve the current qbxml_version the gem is running at. If autoload is true, it will ask Quickbooks (via the current connection) for the qbxml versions it supports, then choose the latest that the gem also supports.



54
55
56
57
58
59
60
# File 'lib/quickbooks.rb', line 54

def qbxml_version(autoload=false)
  @qbxml_version ||= if autoload
    '2.1'
  else
    nil
  end
end

.qbxml_version=(version) ⇒ Object



61
62
63
64
65
66
67
68
# File 'lib/quickbooks.rb', line 61

def qbxml_version=(version)
  warn "Only a subset of QBXML Version 2.1 is available in the demo."
  @qbxml_version = '2.1'
  # Load xsd right away?
  # Also, could run a separate thread for loading this,
  # then join it when needed and harvest the xsd from it.
  # xsd(true)
end

.requestify(requestish) ⇒ Object

Raises:



118
119
120
121
122
123
# File 'lib/quickbooks.rb', line 118

def requestify(requestish)
  QB::QBXMLMsgsRq.options[:onError].default = 'stopOnError'
  request = requestish.class.name =~ /Rq$/ ? QB::QBXML.new(:QBXMLMsgsRq => [requestish]) : requestish
  raise ValidationError, request.to_xml + "\n" + request.errors.join(', ') if !request.valid?
  return request
end

.send_qbxml(qbxml) ⇒ Object



110
111
112
# File 'lib/quickbooks.rb', line 110

def send_qbxml(qbxml)
  @last_response_xml = connection.send_xml("<?xml version=\"1.0\" ?>\n<?qbxml version=\"#{qbxml_version(true)}\" ?>\n#{qbxml}")
end

.send_request(request) ⇒ Object



114
115
116
# File 'lib/quickbooks.rb', line 114

def send_request(request)
  Quickbooks::Support.parse_xml(send_qbxml(request.to_xml))
end

.xsd(autoload = false) ⇒ Object

Returns the XSD data structure parsed from the current qbxml_version. If autoload is true, it will go ahead and parse the XSD for the current version if it is not already parsed and cached.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/quickbooks.rb', line 72

def xsd(autoload=false)
  @xsd ||= {}
  @xsd[qbxml_version(true)] || begin
    @xsd[qbxml_version] = (autoload ? Quickbooks::XSD.parse_file("qbxmlops_demo.xsd", File.dirname(__FILE__) + "/../source/") : nil)
    connector_error_xsd = <<ENDXSD
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:element name="ErrorMessage">
	<xsd:simpleType>
		<xsd:restriction base="STRTYPE" />
	</xsd:simpleType>
</xsd:element>

<xsd:element name="ConnectorError">
	<xsd:complexType>
		<xsd:sequence>
			<xsd:element ref="ErrorMessage" />
		</xsd:sequence>
	</xsd:complexType>
</xsd:element>
ENDXSD
    @xsd[qbxml_version].parse(connector_error_xsd)
  end
  @xsd[qbxml_version]
end