Class: LocoBill::Request
- Inherits:
-
Object
- Object
- LocoBill::Request
- Defined in:
- lib/loco_bill/request.rb
Constant Summary collapse
- NON_OPERATION_WRAPPED_ACTIONS =
[:login, :logout, :getorglist]
- INLINE_PARAMS_ACTIONS =
{:get_list => :object}
Instance Attribute Summary collapse
-
#result ⇒ Object
readonly
Returns the value of attribute result.
Instance Method Summary collapse
-
#action_xml(xml) ⇒ Object
called from build_request_xml, just the xml related to the action we’re doing TODO: refactor into a method that takes a wrapper &block.
- #api(xml_body) ⇒ Object
-
#auto_login ⇒ Object
auto-login & grab session id if we don’t already have one.
- #build_request_xml ⇒ Object
-
#initialize(action, params = {}) ⇒ Request
constructor
A new instance of Request.
-
#params_xml(xml, params) ⇒ Object
recursive, so you can do things like: BillApi.create_vendor :vendor => => ‘Test’.
- #process_response(arr) ⇒ Object
-
#transaction_id ⇒ Object
generate a transaction id for operation requests.
Constructor Details
#initialize(action, params = {}) ⇒ Request
Returns a new instance of Request.
7 8 9 10 11 12 13 |
# File 'lib/loco_bill/request.rb', line 7 def initialize(action, params={}) @action = action.to_sym auto_login @params = params @result = process_response(api(build_request_xml)) end |
Instance Attribute Details
#result ⇒ Object (readonly)
Returns the value of attribute result.
3 4 5 |
# File 'lib/loco_bill/request.rb', line 3 def result @result end |
Instance Method Details
#action_xml(xml) ⇒ Object
called from build_request_xml, just the xml related to the action we’re doing TODO: refactor into a method that takes a wrapper &block
39 40 41 42 43 44 |
# File 'lib/loco_bill/request.rb', line 39 def action_xml(xml) inline_params = INLINE_PARAMS_ACTIONS.has_key?(@action) ? {INLINE_PARAMS_ACTIONS[@action] => @params[INLINE_PARAMS_ACTIONS[@action]]} : nil xml.send(@action, inline_params) do params_xml(xml, @params) end end |
#api(xml_body) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/loco_bill/request.rb', line 75 def api(xml_body) puts "XML BODY: #{xml_body}" if LocoBill::Configuration.debug https = Net::HTTP.new(LocoBill::Configuration.server, 443) https.use_ssl = true https.read_timeout=5 # 5 second timeout https.verify_mode = OpenSSL::SSL::VERIFY_NONE req = Net::HTTP::Post.new(LocoBill::Configuration.api_endpoint) req.body = "request=#{req.send(:urlencode, xml_body)}" # prefixing the request with "request=" showed up in the docs absolutely nowhere. thanks, bill.com. req.content_type = 'application/x-www-form-urlencoded' resp = https.start {|http| http.request(req) } case resp when Net::HTTPSuccess [xml_body, resp.body] else resp.error! end end |
#auto_login ⇒ Object
auto-login & grab session id if we don’t already have one.
16 17 18 19 20 |
# File 'lib/loco_bill/request.rb', line 16 def auto_login if LocoBill::Configuration.session_id.nil? && @action != :login LocoBill::Configuration.session_id = LocoBill.login.result.sessionId end end |
#build_request_xml ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/loco_bill/request.rb', line 22 def build_request_xml operation_wrapped = !NON_OPERATION_WRAPPED_ACTIONS.include?(@action) Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml| xml.request(:version => LocoBill::Configuration::API_VERSION, :applicationkey => LocoBill::Configuration.application_key) { if operation_wrapped # gotta wrap most of the api calls in an "operation" block with a transaction id & session id xml.operation(:transactionId => LocoBill::Configuration.transaction_id, :sessionId => LocoBill::Configuration.session_id) { action_xml(xml) } else action_xml(xml) end } end.to_xml end |
#params_xml(xml, params) ⇒ Object
recursive, so you can do things like: BillApi.create_vendor :vendor => => ‘Test’
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/loco_bill/request.rb', line 48 def params_xml(xml, params) params.each do |k, v| k = 'id_' if k.to_s == 'id' # nokogiri blows up if we try to call 'id', but they have this workaround xml.send(k) { if v.is_a?(Hash) params_xml(xml, v) elsif v.is_a?(Array) v.each do |hash| params_xml(xml, hash) end else if v.is_a?(Time) || v.is_a?(Date) v = v.to_time.strftime("%m/%d/%Y") end xml.text(v) end } end end |
#process_response(arr) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/loco_bill/request.rb', line 96 def process_response(arr) original_request, raw_response = arr puts "RAW RESPONSE: #{raw_response}" if LocoBill::Configuration.debug res = Hash.from_xml(raw_response)['response'] res = res["#{@action}result"] || res["operationresult"] res.symbolize_keys! if res[:status] == 'OK' RequestResult.new(res) elsif res[:loginresult] && res[:loginresult]["status"] == "failed" && res[:loginresult]["errormessage"] == "Invalid Session" # stale session, relogin + try again LocoBill::Configuration.session_id = LocoBill.login.result.sessionId api(original_request) else HoptoadNotifier.notify( :error_class => "LocoBill::RequestError", :error_message => "#{res[:errorcode]}: #{res[:errormessage]}", :parameters => {:raw_response => raw_response, :original_request => original_request} ) if Object.const_defined?(:HoptoadNotifier) raise RequestError.new "#{res[:errorcode]}: #{res[:errormessage]}" end end |
#transaction_id ⇒ Object
generate a transaction id for operation requests
70 71 72 73 |
# File 'lib/loco_bill/request.rb', line 70 def transaction_id ::Configuration.transaction_id += 1 "Transaction#{::Configuration.transaction_id}" end |