fishbowl 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +1 -8
- data/fishbowl.gemspec +4 -4
- data/lib/fishbowl.rb +9 -90
- data/lib/fishbowl/configuration.rb +9 -0
- data/lib/fishbowl/connection.rb +99 -0
- data/lib/fishbowl/errors.rb +9 -2
- data/lib/fishbowl/objects/account.rb +0 -26
- data/lib/fishbowl/objects/base_object.rb +25 -8
- data/lib/fishbowl/requests.rb +3 -4
- data/lib/fishbowl/requests/get_account_balance.rb +15 -0
- data/lib/fishbowl/requests/get_account_list.rb +13 -0
- data/lib/fishbowl/requests/get_carrier_list.rb +3 -2
- data/lib/fishbowl/requests/get_customer_list.rb +12 -0
- data/lib/fishbowl/requests/get_customer_name_list.rb +12 -0
- data/lib/fishbowl/requests/get_export_list.rb +12 -0
- data/lib/fishbowl/requests/get_import_list.rb +12 -0
- data/lib/fishbowl/requests/get_location_group_list.rb +12 -0
- data/lib/fishbowl/requests/get_location_list.rb +12 -0
- data/lib/fishbowl/requests/get_uom_list.rb +12 -0
- data/lib/fishbowl/requests/get_vendor_list.rb +12 -0
- data/lib/fishbowl/requests/get_vendor_name_list.rb +12 -0
- data/lib/fishbowl/requests/get_work_order_list.rb +12 -0
- data/lib/fishbowl/requests/void_sales_order.rb +18 -0
- data/lib/fishbowl/version.rb +1 -1
- data/lib/status_codes.yml +183 -0
- data/spec/objects/account_spec.rb +0 -41
- data/spec/requests/calculate_sales_order_spec.rb +48 -0
- data/spec/requests/close_short_sales_order_spec.rb +45 -0
- data/spec/requests/cycle_count_spec.rb +49 -0
- data/spec/requests/delete_sales_order_spec.rb +45 -0
- data/spec/requests/export_spec.rb +45 -0
- data/spec/requests/get_account_balance_spec.rb +52 -0
- data/spec/requests/get_account_list_spec.rb +51 -0
- data/spec/requests/get_customer_list_spec.rb +51 -0
- data/spec/requests/get_customer_name_list_spec.rb +45 -0
- data/spec/requests/get_customer_spec.rb +45 -0
- data/spec/requests/get_export_list_spec.rb +45 -0
- data/spec/requests/get_import_list_spec.rb +45 -0
- data/spec/requests/get_inventory_quantity_spec.rb +65 -0
- data/spec/requests/get_light_part_list_spec.rb +51 -0
- data/spec/requests/get_location_group_list_spec.rb +45 -0
- data/spec/requests/get_location_list_spec.rb +45 -0
- data/spec/requests/get_next_number_spec.rb +45 -0
- data/spec/requests/get_part_cost_spec.rb +45 -0
- data/spec/requests/get_part_information_spec.rb +45 -0
- data/spec/requests/get_part_list_spec.rb +65 -0
- data/spec/requests/get_pick_spec.rb +45 -0
- data/spec/requests/get_product_information_spec.rb +46 -0
- data/spec/requests/get_purchase_order_list_spec.rb +45 -0
- data/spec/requests/get_receipt_spec.rb +49 -0
- data/spec/requests/get_receiving_list_spec.rb +49 -0
- data/spec/requests/get_sales_order_list_spec.rb +49 -0
- data/spec/requests/get_ship_list_spec.rb +49 -0
- data/spec/requests/get_ship_now_list_spec.rb +48 -0
- data/spec/requests/get_shipment_spec.rb +45 -0
- data/spec/requests/get_system_property_spec.rb +45 -0
- data/spec/requests/get_total_inventory_spec.rb +46 -0
- data/spec/requests/get_transfer_order_list_spec.rb +45 -0
- data/spec/requests/get_uom_list_spec.rb +45 -0
- data/spec/requests/get_user_property_spec.rb +45 -0
- data/spec/requests/get_vendor_list_spec.rb +45 -0
- data/spec/requests/get_vendor_name_list_spec.rb +45 -0
- data/spec/requests/get_vendor_spec.rb +48 -0
- data/spec/requests/get_work_order_list_spec.rb +45 -0
- data/spec/requests/get_work_order_spec.rb +45 -0
- data/spec/requests/import_spec.rb +49 -0
- data/spec/requests/issues_sales_order_spec.rb +45 -0
- data/spec/requests/load_sales_order_spec.rb +45 -0
- data/spec/requests/load_transfer_order_spec.rb +45 -0
- data/spec/requests/location_query_spec.rb +49 -0
- data/spec/requests/make_payment_spec.rb +50 -0
- data/spec/requests/move_spec.rb +49 -0
- data/spec/requests/part_query_spec.rb +46 -0
- data/spec/requests/pick_query_spec.rb +49 -0
- data/spec/requests/print_report_spec.rb +48 -0
- data/spec/requests/product_query_spec.rb +46 -0
- data/spec/requests/quick_ship_spec.rb +45 -0
- data/spec/requests/quickbooks_export_spec.rb +43 -0
- data/spec/requests/save_customer_spec.rb +48 -0
- data/spec/requests/save_discount_spec.rb +48 -0
- data/spec/requests/save_pick_spec.rb +48 -0
- data/spec/requests/save_purchase_order_spec.rb +48 -0
- data/spec/requests/save_receipt_spec.rb +48 -0
- data/spec/requests/save_report_spec.rb +49 -0
- data/spec/requests/save_sales_order_spec.rb +48 -0
- data/spec/requests/save_shipment_spec.rb +48 -0
- data/spec/requests/save_tax_rate_spec.rb +48 -0
- data/spec/requests/save_transfer_order_spec.rb +48 -0
- data/spec/requests/save_upc_spec.rb +48 -0
- data/spec/requests/save_vendor_spec.rb +48 -0
- data/spec/requests/save_work_order_spec.rb +48 -0
- data/spec/requests/set_default_part_location_spec.rb +48 -0
- data/spec/requests/set_system_property_spec.rb +48 -0
- data/spec/requests/set_user_property_spec.rb +48 -0
- data/spec/requests/ship_spec.rb +48 -0
- data/spec/requests/void_sales_order_spec.rb +43 -0
- metadata +167 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5de36e305db8f0ee23f26a5e54347bf31200326a
|
4
|
+
data.tar.gz: 9c43fd84b6929bd7013cbb1f9080247d243370fd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1e234e842add2ce0df6a7204b792a16033f94f6a728a30768993512defbb76bbcba66b1cb85ec099245e5b2ecec82b72918462e3e6b711d406e1dce2b7b9e992
|
7
|
+
data.tar.gz: 3a54c1b6b70b52c8df8654a89d5d143716b77e065496ef3c61b8d42503c5457e0df90adda68744ff3554053472dfd4a91b06ddbeeb3d2760fe6429e60d95024b
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/fishbowl.gemspec
CHANGED
@@ -6,11 +6,11 @@ require 'fishbowl/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "fishbowl"
|
8
8
|
gem.version = Fishbowl::VERSION
|
9
|
-
gem.authors = ["James Thompson"]
|
10
|
-
gem.email = ["james@plainprograms.com"]
|
11
|
-
gem.description = %q{Provides an interface to the Fishbowl Inventory API
|
9
|
+
gem.authors = ["James Thompson, Simeon Berns"]
|
10
|
+
gem.email = ["james@plainprograms.com, simeonberns@gmail.com"]
|
11
|
+
gem.description = %q{Provides an interface to the Fishbowl Inventory API}
|
12
12
|
gem.summary = %q{Fishbowl Inventory API}
|
13
|
-
gem.homepage = "https://github.com/
|
13
|
+
gem.homepage = "https://github.com/flameofzion/fishbowl"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/fishbowl.rb
CHANGED
@@ -10,99 +10,18 @@ require 'fishbowl/version'
|
|
10
10
|
require 'fishbowl/errors'
|
11
11
|
require 'fishbowl/requests'
|
12
12
|
require 'fishbowl/objects'
|
13
|
+
require 'fishbowl/connection'
|
14
|
+
require 'fishbowl/configuration'
|
13
15
|
|
14
16
|
module Fishbowl # :nodoc:
|
15
|
-
class Connection
|
16
|
-
include Singleton
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@host = options[:host]
|
22
|
-
@port = options[:port].nil? ? 28192 : options[:port]
|
23
|
-
|
24
|
-
@connection = TCPSocket.new @host, @port
|
25
|
-
|
26
|
-
self.instance
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.login(options = {})
|
30
|
-
raise Fishbowl::Errors::ConnectionNotEstablished if @connection.nil?
|
31
|
-
raise Fishbowl::Errors::MissingUsername if options[:username].nil?
|
32
|
-
raise Fishbowl::Errors::MissingPassword if options[:password].nil?
|
33
|
-
|
34
|
-
@username, @password = options[:username], options[:password]
|
35
|
-
|
36
|
-
code, message, _ = Fishbowl::Objects::BaseObject.new.send_request(login_request, 'LoginRs')
|
37
|
-
|
38
|
-
Fishbowl::Errors.confirm_success_or_raise(code, message)
|
39
|
-
|
40
|
-
self.instance
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.host
|
44
|
-
@host
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.port
|
48
|
-
@port
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.username
|
52
|
-
@username
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.password
|
56
|
-
@password
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.send(request, expected_response = 'FbiMsgRs')
|
60
|
-
write(request)
|
61
|
-
get_response(expected_response)
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.close
|
65
|
-
@connection.close
|
66
|
-
@connection = nil
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def self.login_request
|
72
|
-
Nokogiri::XML::Builder.new do |xml|
|
73
|
-
xml.request {
|
74
|
-
xml.LoginRq {
|
75
|
-
xml.IAID "fishbowl-ruby"
|
76
|
-
xml.IAName "Fishbowl Ruby Gem"
|
77
|
-
xml.IADescription "Fishbowl Ruby Gem"
|
78
|
-
xml.UserName @username
|
79
|
-
xml.UserPassword encoded_password
|
80
|
-
}
|
81
|
-
}
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def self.encoded_password
|
86
|
-
Base64.encode64(@password)
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.write(request)
|
90
|
-
body = request.to_xml
|
91
|
-
size = [body.size].pack("L>")
|
92
|
-
|
93
|
-
@connection.write(size)
|
94
|
-
@connection.write(body)
|
95
|
-
end
|
96
|
-
|
97
|
-
def self.get_response(expectation)
|
98
|
-
length = @connection.recv(3).unpack('L>').join('').to_i
|
99
|
-
response = Nokogiri::XML.parse(@connection.recv(length))
|
100
|
-
|
101
|
-
status_code = response.xpath("//#{expectation}/@statusCode").first.value
|
102
|
-
status_message = response.xpath("//#{expectation}/@statusMessage").first.value
|
103
|
-
|
104
|
-
[status_code, status_message, response]
|
105
|
-
end
|
18
|
+
class << self
|
19
|
+
attr_accessor :configuration
|
20
|
+
end
|
106
21
|
|
22
|
+
def self.configure
|
23
|
+
self.configuration ||= Configuration.new
|
24
|
+
yield(configuration)
|
107
25
|
end
|
26
|
+
|
108
27
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Fishbowl
|
2
|
+
class Connection
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def self.connect()
|
6
|
+
raise Fishbowl::Errors::MissingHost if Fishbowl.configuration.host.nil?
|
7
|
+
|
8
|
+
@host = Fishbowl.configuration.host
|
9
|
+
@port = Fishbowl.configuration.port.nil? ? 28192 : Fishbowl.configuration.port
|
10
|
+
|
11
|
+
@connection = TCPSocket.new @host, @port
|
12
|
+
|
13
|
+
self.instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.login()
|
17
|
+
raise Fishbowl::Errors::ConnectionNotEstablished if @connection.nil?
|
18
|
+
raise Fishbowl::Errors::MissingUsername if Fishbowl.configuration.host.nil?
|
19
|
+
raise Fishbowl::Errors::MissingPassword if Fishbowl.configuration.host.nil?
|
20
|
+
|
21
|
+
@username = Fishbowl.configuration.username
|
22
|
+
@password = Fishbowl.configuration.password
|
23
|
+
|
24
|
+
code, _ = Fishbowl::Objects::BaseObject.new.send_request(login_request)
|
25
|
+
Fishbowl::Errors.confirm_success_or_raise(code)
|
26
|
+
|
27
|
+
self.instance
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.host
|
31
|
+
@host
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.port
|
35
|
+
@port
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.username
|
39
|
+
@username
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.password
|
43
|
+
@password
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.send(request, expected_response = 'FbiMsgsRs')
|
47
|
+
puts 'opening connection...' if Fishbowl.configuration.debug.eql? true
|
48
|
+
puts request if Fishbowl.configuration.debug.eql? true
|
49
|
+
puts 'waiting for response...' if Fishbowl.configuration.debug.eql? true
|
50
|
+
write(request)
|
51
|
+
get_response(expected_response)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.close
|
55
|
+
@connection.close
|
56
|
+
@connection = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def self.login_request
|
62
|
+
Nokogiri::XML::Builder.new do |xml|
|
63
|
+
xml.request {
|
64
|
+
xml.LoginRq {
|
65
|
+
xml.IAID Fishbowl.configuration.app_id
|
66
|
+
xml.IAName Fishbowl.configuration.app_name
|
67
|
+
xml.IADescription Fishbowl.configuration.app_description
|
68
|
+
xml.UserName Fishbowl.configuration.username
|
69
|
+
xml.UserPassword encoded_password
|
70
|
+
}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.encoded_password
|
76
|
+
Digest::MD5.base64digest(@password)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.write(request)
|
80
|
+
body = request.to_xml
|
81
|
+
size = [body.size].pack("L>")
|
82
|
+
@connection.write(size)
|
83
|
+
@connection.write(body)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.get_response(expectation)
|
87
|
+
length = @connection.recv(4).unpack('L>').join('').to_i
|
88
|
+
response = Nokogiri::XML.parse(@connection.recv(length))
|
89
|
+
|
90
|
+
puts "Looking for '#{expectation}' node in: " if Fishbowl.configuration.debug.eql? true
|
91
|
+
puts response if Fishbowl.configuration.debug.eql? true
|
92
|
+
|
93
|
+
status_code = response.xpath("/FbiXml/#{expectation}").attr("statusCode").value
|
94
|
+
|
95
|
+
[status_code, response]
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
data/lib/fishbowl/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
module Fishbowl::Errors
|
2
4
|
class ConnectionNotEstablished < RuntimeError; end;
|
3
5
|
class MissingHost < ArgumentError; end;
|
@@ -6,7 +8,12 @@ module Fishbowl::Errors
|
|
6
8
|
|
7
9
|
class StatusError < RuntimeError; end;
|
8
10
|
|
9
|
-
def self.confirm_success_or_raise(code
|
10
|
-
code.to_i == 1000 ? true : raise(StatusError,
|
11
|
+
def self.confirm_success_or_raise(code)
|
12
|
+
code.to_i == 1000 ? true : raise(StatusError, get_status(code.to_i))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.get_status(code)
|
16
|
+
status_codes = YAML.load_file('./lib/status_codes.yml')['codes']
|
17
|
+
status_codes[code]['message']
|
11
18
|
end
|
12
19
|
end
|
@@ -11,31 +11,5 @@ module Fishbowl::Objects
|
|
11
11
|
parse_attributes
|
12
12
|
self
|
13
13
|
end
|
14
|
-
|
15
|
-
def self.get_list
|
16
|
-
_, _, response = BaseObject.new.send_request("GetAccountListRq", "GetAccountListRs")
|
17
|
-
|
18
|
-
results = []
|
19
|
-
|
20
|
-
response.xpath("//Account").each do |account_xml|
|
21
|
-
results << Account.new(account_xml)
|
22
|
-
end
|
23
|
-
|
24
|
-
results
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.get_balance(account)
|
28
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
29
|
-
xml.request {
|
30
|
-
xml.GetAccountBalanceRq {
|
31
|
-
xml.Account (account.is_a?(Account) ? account.name : account)
|
32
|
-
}
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
_, _, response = BaseObject.new.send_request(builder, "GetAccountBalanceRs")
|
37
|
-
|
38
|
-
response.xpath("//Account/Balance").first.inner_text
|
39
|
-
end
|
40
14
|
end
|
41
15
|
end
|
@@ -1,11 +1,25 @@
|
|
1
1
|
module Fishbowl::Objects
|
2
2
|
class BaseObject
|
3
|
-
|
3
|
+
@@ticket = nil
|
4
4
|
|
5
|
-
def send_request(request, expected_response = '
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def send_request(request, expected_response = 'FbiMsgsRs')
|
6
|
+
result = nil
|
7
|
+
5.times do |i|
|
8
|
+
puts "REQUEST ATTEMPT: #{i}" if Fishbowl.configuration.debug.eql? true
|
9
|
+
begin
|
10
|
+
code, response = Fishbowl::Connection.send(build_request(request), expected_response)
|
11
|
+
raise "No response" if response.nil?
|
12
|
+
Fishbowl::Errors.confirm_success_or_raise(code)
|
13
|
+
@@ticket = response.css("FbiXml Ticket Key").text
|
14
|
+
puts 'RESPONSE SUCCEEDED' if Fishbowl.configuration.debug.eql? true
|
15
|
+
result = [code, nil, response]
|
16
|
+
break
|
17
|
+
rescue NoMethodError => nme
|
18
|
+
puts 'FAILED TO GET RESPONSE' if Fishbowl.configuration.debug.eql? true
|
19
|
+
sleep 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
return result
|
9
23
|
end
|
10
24
|
|
11
25
|
protected
|
@@ -35,12 +49,14 @@ module Fishbowl::Objects
|
|
35
49
|
private
|
36
50
|
|
37
51
|
def build_request(request)
|
38
|
-
Nokogiri::XML::Builder.new do |xml|
|
52
|
+
new_req = Nokogiri::XML::Builder.new do |xml|
|
39
53
|
xml.FbiXml {
|
40
|
-
if
|
54
|
+
if @@ticket.nil?
|
41
55
|
xml.Ticket
|
42
56
|
else
|
43
|
-
xml.Ticket
|
57
|
+
xml.Ticket {
|
58
|
+
xml.Key @@ticket
|
59
|
+
}
|
44
60
|
end
|
45
61
|
|
46
62
|
xml.FbiMsgsRq {
|
@@ -52,6 +68,7 @@ module Fishbowl::Objects
|
|
52
68
|
}
|
53
69
|
}
|
54
70
|
end
|
71
|
+
Nokogiri::XML(new_req.to_xml).root
|
55
72
|
end
|
56
73
|
|
57
74
|
end
|
data/lib/fishbowl/requests.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Fishbowl; module Requests; end; end
|
2
2
|
|
3
|
-
|
4
|
-
require
|
5
|
-
|
6
|
-
require 'fishbowl/requests/get_carrier_list'
|
3
|
+
Dir.glob(File.join(File.expand_path("../requests/", __FILE__), "**.rb")).each do |file|
|
4
|
+
require file
|
5
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.get_account_balance(account_name)
|
3
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
4
|
+
xml.request {
|
5
|
+
xml.GetAccountBalanceRq {
|
6
|
+
xml.Account (account.is_a?(Account) ? account.name : account)
|
7
|
+
}
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
_, _, response = Fishbowl::Objects::BaseObject.new.send_request(builder, "GetAccountBalanceRs")
|
12
|
+
|
13
|
+
response.xpath("//Account/Balance").first.inner_text
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.get_account_list
|
3
|
+
_, _, response = Fishbowl::Objects::BaseObject.new.send_request('GetAccountListRq', 'GetAccountListRs')
|
4
|
+
|
5
|
+
results = []
|
6
|
+
|
7
|
+
response.xpath("//Account").each do |account_xml|
|
8
|
+
results << Account.new(account_xml)
|
9
|
+
end
|
10
|
+
|
11
|
+
results
|
12
|
+
end
|
13
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Fishbowl::Requests
|
2
2
|
def self.get_carrier_list
|
3
|
-
_, _, response = Fishbowl::Objects::BaseObject.new.send_request('CarrierListRq', 'CarrierListRs')
|
3
|
+
_, _, response = Fishbowl::Objects::BaseObject.new.send_request('CarrierListRq', 'FbiMsgsRs/CarrierListRs')
|
4
4
|
|
5
5
|
results = []
|
6
|
-
|
6
|
+
|
7
|
+
response.xpath("//Carriers/Name").each do |carrier_xml|
|
7
8
|
results << Fishbowl::Objects::Carrier.new(carrier_xml)
|
8
9
|
end
|
9
10
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.get_customer_list
|
3
|
+
_, _, response = Fishbowl::Objects::BaseObject.new.send_request('CustomerListRq', 'CustomerListRs')
|
4
|
+
|
5
|
+
results = []
|
6
|
+
response.xpath("//Customer").each do |customer_xml|
|
7
|
+
results << Fishbowl::Objects::Customer.new(customer_xml)
|
8
|
+
end
|
9
|
+
|
10
|
+
results
|
11
|
+
end
|
12
|
+
end
|