Class: Qbxml::Response

Inherits:
Object show all
Defined in:
lib/qbxml/response.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml_or_hash) ⇒ Response

Returns a new instance of Response.



73
74
75
76
77
78
79
80
81
# File 'lib/qbxml/response.rb', line 73

def initialize(xml_or_hash)
  if(xml_or_hash.is_a?(Hash))
    self.import_from_hash(xml_or_hash)
  elsif(xml_or_hash.is_a?(String))
    self.import_from_xml(xml_or_hash)
  else
    raise ArgumentError, "Qbxml::ResponseSet must be initialized with either a Hash or an xml-formatted String."
  end
end

Instance Attribute Details

#messageObject

Returns the value of attribute message.



69
70
71
# File 'lib/qbxml/response.rb', line 69

def message
  @message
end

#raw_responseObject

For Development purposes:



71
72
73
# File 'lib/qbxml/response.rb', line 71

def raw_response
  @raw_response
end

#response_typeObject

Returns the value of attribute response_type.



69
70
71
# File 'lib/qbxml/response.rb', line 69

def response_type
  @response_type
end

#ret_itemsObject

Returns the value of attribute ret_items.



69
70
71
# File 'lib/qbxml/response.rb', line 69

def ret_items
  @ret_items
end

#severityObject

Returns the value of attribute severity.



69
70
71
# File 'lib/qbxml/response.rb', line 69

def severity
  @severity
end

#statusObject

Returns the value of attribute status.



69
70
71
# File 'lib/qbxml/response.rb', line 69

def status
  @status
end

Class Method Details

.from_hash(hsh) ⇒ Object



133
134
135
# File 'lib/qbxml/response.rb', line 133

def from_hash(hsh)
  new.import_from_hash(hsh)
end

.from_xml(xml) ⇒ Object



130
131
132
# File 'lib/qbxml/response.rb', line 130

def from_xml(xml)
  new.import_from_xml(xml)
end

Instance Method Details

#error?Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/qbxml/response.rb', line 144

def error?
  !success?
end

#import_from_hash(hsh) ⇒ Object

Raises:

  • (ArgumentError)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/qbxml/response.rb', line 87

def import_from_hash(hsh)
  raise ArgumentError, "Hash passed to Qbxml::Response.from_hash must contain only one top-level key" unless hsh.keys.length == 1
  name = hsh.keys.first
  # for development
  self.raw_response = hsh
  # * * * *
  hsh = hsh[name]

  self.status = hsh['statusCode'].to_i
  self.severity = hsh['statusSeverity']
  self.message = hsh['statusMessage']
  # if self.status == 0 # Status is good, proceed with eating the request.
  # <ListDeletedQueryRs requestID="5" statusCode="0" statusSeverity="Info" statusMessage="Status OK">
  #   <ListDeletedRet>
  #     <ListDelType>Customer</ListDelType>
  #     <ListID>80000030-1203622308</ListID>
  #     <TimeCreated>2008-02-21T14:31:48-05:00</TimeCreated>
  #     <TimeDeleted>2008-03-18T17:31:12-05:00</TimeDeleted>
  #     <FullName>Rachel Parker</FullName>
  #   </ListDeletedRet>
  # </ListDeletedQueryRs>
    if m = name.match(/^(List|Txn)Del(etedQuery)?Rs$/)
      # (List|Txn)DelRs, or (List|Txn)DeletedQueryRs - both return just a few attributes, like ListID / TxnID and TimeDeleted
      list_or_txn = m[1]
      long_name = m[1]+'Del'+m[2].to_s
      ret_key = long_name.gsub(/Query$/,'')+'Ret'
      self.ret_items = hsh[ret_key].is_a?(Array) ? hsh[ret_key] : [hsh[ret_key]].compact # Force to be an array - it's return items!
      self.response_type = self.ret_items.empty? ? m[1] : self.ret_items[0][list_or_txn+'DelType']
    elsif m = name.match(/^((?:[A-Za-z][a-z]+)+)(Query|Mod|Add)Rs$/)
      self.response_type = m[1]
      self.ret_items = hsh[self.response_type+'Ret']
    else
      raise "Could not read this response:\n#{self.raw_response.inspect}"
    end
  # else # Status is bad.
    
  # end
  # puts self.inspect
  self
end

#import_from_xml(xml) ⇒ Object



83
84
85
86
# File 'lib/qbxml/response.rb', line 83

def import_from_xml(xml)
  self.import_from_hash(xml.formatted(:xml).to_hash)
  self
end

#instantiatable?Boolean

Just checks to see if it can create an object of this type, and if there is actually data to instantiate

Returns:

  • (Boolean)


138
139
140
# File 'lib/qbxml/response.rb', line 138

def instantiatable? # Just checks to see if it can create an object of this type, and if there is actually data to instantiate
  self.response_type ? (Quickbooks.const_defined?(self.response_type) && self.ret_items.is_a?(Hash) || (self.ret_items.is_a?(Array) && self.ret_items[0].is_a?(Hash))) : false
end

#instantiate(reinstantiate = nil) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/qbxml/response.rb', line 148

def instantiate(reinstantiate=nil)
  objs = []
  (self.ret_items.is_a?(Array) ? self.ret_items : [self.ret_items]).each do |ret_item|
    obj = reinstantiate if reinstantiate
    if instantiatable?
      if self.status == 0
        if obj.nil?
          obj = "Quickbooks::#{self.response_type}".constantize.instantiate(ret_item)
        else
          obj.class.instantiate(obj, ret_item)
        end
      else
        # Instantiatable, but some error status. For any error status
        if obj.nil? # Must be a new object. Just as well, create a new object WITHOUT any original_attributes.
          obj = "Quickbooks::#{self.response_type}".constantize.new(ret_item)
        else # An existing object. Must be an update or delete request. Update object's original_attributes.
          updated = []
          ret_item.each do |k,v|
            k = k.underscore
            if obj.original_values[k] != v
              updated << k
              if obj.class.instance_variable_get('@object_properties').has_key?(k.to_sym)
                obj.original_values[k] = obj.class.instance_variable_get('@object_properties')[k.to_sym].new(v)
              else
                obj.original_values[k] = v
              end
            end
          end
          # Update object's 'read-only' attributes (as well as in the original_values):
          obj.class.read_only.stringify_values.camelize_values.each do |k|
            obj.send(k.underscore + '=', ret_item[k]) if ret_item.has_key?(k) && obj.respond_to?(k.underscore + '=')
          end
          self.message = self.message + " Other properties were out of date: [" + updated.join(', ') + '].'
        end
        obj.errors << {:code => self.status, :message => self.message, :response => self}
      end
    else
      if self.status == 0
        obj.errors << {:code => nil, :message => "Cannot instantiate object of type #{self.response_type}!", :response => self}
      else
        obj.errors << {:code => self.status, :message => self.message, :response => self}
      end
    end
    obj.response_log << self unless obj.nil?
    objs << obj
  end
  objs.length > 1 ? objs : objs[0] # Single or nil if not more than one.
end

#success?Boolean

Returns:

  • (Boolean)


141
142
143
# File 'lib/qbxml/response.rb', line 141

def success?
  self.status == 0
end