fishbowl 0.0.3 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +5 -0
- data/README.md +25 -5
- data/fishbowl.gemspec +2 -2
- data/lib/fishbowl/connection.rb +8 -7
- data/lib/fishbowl/errors.rb +15 -12
- data/lib/fishbowl/objects/base_object.rb +6 -19
- data/lib/fishbowl/requests/get_carrier_list.rb +3 -2
- data/lib/fishbowl/requests/get_product.rb +18 -0
- data/lib/fishbowl/requests/get_product_price.rb +21 -0
- data/lib/fishbowl/requests/inventory_quantity.rb +17 -0
- data/lib/fishbowl/requests/load_sales_order.rb +21 -0
- data/lib/fishbowl/requests/save_sales_order.rb +86 -0
- data/lib/fishbowl/requests/total_inventory.rb +18 -0
- data/lib/fishbowl/version.rb +1 -1
- data/lib/status_codes.yml +51 -51
- data/spec/connection_spec.rb +99 -99
- data/spec/errors_spec.rb +11 -9
- data/spec/spec_helper.rb +48 -46
- metadata +20 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c4d75a0a37f3de2f16fbcfc480808e9e3def4684a2bb1fb4709b8b930c2d3412
|
4
|
+
data.tar.gz: 6eea54698890bb06690f41d108a1a53c827cde5fa41c1f345463b8afdcecfadd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 277e8d820495462b80418a85a795d035cfec611d9f7ae1d9281f0e5888f53b420ae7df70a3aff6e70645f7141118941c6c7d4ea0f7c451d214a4b8a280a950c8
|
7
|
+
data.tar.gz: 55a17bafa085547969d508e1a03213659d7eb653357811effcbe9dddee40262eaf9f1a5b29a39fce74c2b3e274adb44409c410206f0d2daf755e6aca6066fdff
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,10 +2,6 @@
|
|
2
2
|
|
3
3
|
Provides an interface to the Fishbowl Inventory API.
|
4
4
|
|
5
|
-
[](https://travis-ci.org/readyproject/fishbowl)
|
6
|
-
[](https://codeclimate.com/github/readyproject/fishbowl)
|
7
|
-
[](https://gemnasium.com/readyproject/fishbowl)
|
8
|
-
|
9
5
|
## Requirements
|
10
6
|
|
11
7
|
A Ruby 1.9 compatible interpreter
|
@@ -26,7 +22,31 @@ Or install it yourself as:
|
|
26
22
|
|
27
23
|
## Usage
|
28
24
|
|
29
|
-
|
25
|
+
Add this to your env.rb file or as an initializer
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
Fishbowl.configure do |config|
|
29
|
+
config.username = "joe"
|
30
|
+
config.password = "joes_password"
|
31
|
+
config.host = "999.888.77.666"
|
32
|
+
config.app_id = "1234"
|
33
|
+
config.app_name = "Fishbowl Ruby Gem"
|
34
|
+
config.app_description = "Fishbowl Ruby Gem"
|
35
|
+
config.debug = true
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
Now you are setup to make API calls in your application code
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
Fishbowl::Connection.connect
|
43
|
+
Fishbowl::Connection.login
|
44
|
+
carriers = Fishbowl::Requests.get_carrier_list
|
45
|
+
```
|
46
|
+
|
47
|
+
The 'connect' method establishes the connection socket to the server, the 'login' method authenticates the connection to the server using a username and password.
|
48
|
+
|
49
|
+
Once the login method is successful (The Fishbowl API responds with statusCode=1000 for successful requests, see a [complete list](../master/lib/status_codes.yml) of status codes)
|
30
50
|
|
31
51
|
## Contributing
|
32
52
|
|
data/fishbowl.gemspec
CHANGED
@@ -10,12 +10,12 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.email = ["james@plainprograms.com, simeonberns@gmail.com"]
|
11
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/zion/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) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_dependency 'nokogiri', '
|
20
|
+
gem.add_dependency 'nokogiri', '>= 1.8.5'
|
21
21
|
end
|
data/lib/fishbowl/connection.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
1
3
|
module Fishbowl
|
2
4
|
class Connection
|
3
5
|
include Singleton
|
@@ -24,6 +26,8 @@ module Fishbowl
|
|
24
26
|
code, _ = Fishbowl::Objects::BaseObject.new.send_request(login_request)
|
25
27
|
Fishbowl::Errors.confirm_success_or_raise(code)
|
26
28
|
|
29
|
+
raise "Login failed" unless code.eql? "1000"
|
30
|
+
|
27
31
|
self.instance
|
28
32
|
end
|
29
33
|
|
@@ -84,14 +88,11 @@ module Fishbowl
|
|
84
88
|
end
|
85
89
|
|
86
90
|
def self.get_response(expectation)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
puts "Looking for '#{expectation}' node in: " if Fishbowl.configuration.debug.eql? true
|
91
|
+
puts "reading response" if Fishbowl.configuration.debug.eql? true
|
92
|
+
length = @connection.read(4).unpack('L>').join('').to_i
|
93
|
+
response = Nokogiri::XML.parse(@connection.read(length))
|
91
94
|
puts response if Fishbowl.configuration.debug.eql? true
|
92
|
-
|
93
|
-
status_code = response.xpath("/FbiXml/#{expectation}").attr("statusCode").value
|
94
|
-
|
95
|
+
status_code = response.xpath("/FbiXml/FbiMsgsRs").attr("statusCode").value
|
95
96
|
[status_code, response]
|
96
97
|
end
|
97
98
|
|
data/lib/fishbowl/errors.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
-
module Fishbowl
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Fishbowl
|
4
|
+
module Errors
|
5
|
+
class ConnectionNotEstablished < RuntimeError; end;
|
6
|
+
class MissingHost < ArgumentError; end;
|
7
|
+
class MissingUsername < ArgumentError; end;
|
8
|
+
class MissingPassword < ArgumentError; end;
|
9
|
+
class EmptyResponse < RuntimeError; end;
|
8
10
|
|
9
|
-
|
11
|
+
class StatusError < RuntimeError; end;
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
def self.confirm_success_or_raise(code)
|
14
|
+
(code.to_i.eql? 1000) ? true : raise(StatusError, get_status(code))
|
15
|
+
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
def self.get_status(code)
|
18
|
+
status_codes = YAML.load_file('./lib/status_codes.yml')['codes']
|
19
|
+
status_codes[code]['message']
|
20
|
+
end
|
18
21
|
end
|
19
22
|
end
|
@@ -1,25 +1,12 @@
|
|
1
1
|
module Fishbowl::Objects
|
2
2
|
class BaseObject
|
3
3
|
@@ticket = nil
|
4
|
-
|
5
4
|
def send_request(request, expected_response = 'FbiMsgsRs')
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
5
|
+
code, response = Fishbowl::Connection.send(build_request(request), expected_response)
|
6
|
+
Fishbowl::Errors.confirm_success_or_raise(code)
|
7
|
+
puts "Response successful" if Fishbowl.configuration.debug.eql? true
|
8
|
+
@@ticket = response.xpath("/FbiXml/Ticket/Key").text
|
9
|
+
[code, response]
|
23
10
|
end
|
24
11
|
|
25
12
|
protected
|
@@ -41,7 +28,7 @@ module Fishbowl::Objects
|
|
41
28
|
end
|
42
29
|
|
43
30
|
instance_var = '@' + instance_var
|
44
|
-
value = @xml.
|
31
|
+
value = @xml.children.nil? ? nil : @xml.children.text
|
45
32
|
instance_variable_set(instance_var, value)
|
46
33
|
end
|
47
34
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Fishbowl::Requests
|
2
2
|
def self.get_carrier_list
|
3
|
-
|
4
|
-
|
3
|
+
puts "getting carriers"
|
4
|
+
code, response = Fishbowl::Objects::BaseObject.new.send_request('CarrierListRq', 'FbiMsgsRs/CarrierListRs')
|
5
|
+
|
5
6
|
results = []
|
6
7
|
|
7
8
|
response.xpath("//Carriers/Name").each do |carrier_xml|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.get_product(product_number)
|
3
|
+
raise ArgumentError if product_number.nil?
|
4
|
+
|
5
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
6
|
+
xml.request {
|
7
|
+
xml.ProductGetRq {
|
8
|
+
xml.Number product_number
|
9
|
+
xml.GetImage false
|
10
|
+
}
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
code, response = Fishbowl::Objects::BaseObject.new.send_request(builder, "ProductGetRs")
|
15
|
+
|
16
|
+
response.xpath("//FbiXml/FbiMsgsRs/ProductGetRs/Product")
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.get_product_price(options)
|
3
|
+
options.symbolize_keys
|
4
|
+
|
5
|
+
%w{product_number customer_name qauntity date}.each do |required_field|
|
6
|
+
raise ArgumentError if options[required_field.to_sym].nil?
|
7
|
+
end
|
8
|
+
|
9
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
10
|
+
xml.request {
|
11
|
+
xml.ProductPriceRq {
|
12
|
+
xml.ProductNumber
|
13
|
+
}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
_, _, response = Fishbowl::Objects::BaseObject.new.send_request(builder, "GetAccountBalanceRs")
|
18
|
+
|
19
|
+
response.xpath("//Account/Balance").first.inner_text
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.inventory_quantity(part_num)
|
3
|
+
raise ArgumentError if part_num.nil?
|
4
|
+
|
5
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
6
|
+
xml.request {
|
7
|
+
xml.InvQtyRq {
|
8
|
+
xml.PartNum part_num
|
9
|
+
}
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
code, response = Fishbowl::Objects::BaseObject.new.send_request(builder, "InvQtyRs")
|
14
|
+
|
15
|
+
response.xpath("//FbiXml/FbiMsgsRs/InvQtyRs")
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.load_sales_order(order_number)
|
3
|
+
raise Fishbowl::Errors.ArgumentError if order_number.nil?
|
4
|
+
request = load_order_request(order_number)
|
5
|
+
Fishbowl::Objects::BaseObject.new.send_request(request, 'LoadSORs')
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def self.load_order_request(order_number)
|
11
|
+
Nokogiri::XML::Builder.new do |xml|
|
12
|
+
xml.request {
|
13
|
+
xml.LoadSORq {
|
14
|
+
xml.Number order_number.to_s
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.save_sales_order(options)
|
3
|
+
# options = options.symbolize_keys
|
4
|
+
#
|
5
|
+
# %w{number salesman customer_name status
|
6
|
+
# items}.each do |required_field|
|
7
|
+
# raise ArgumentError if options[required_field.to_sym].nil?
|
8
|
+
# end
|
9
|
+
|
10
|
+
request = format_sales_order(options)
|
11
|
+
Fishbowl::Objects::BaseObject.new.send_request(request, 'SaveSORs')
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def self.format_sales_order(sales_order)
|
17
|
+
Nokogiri::XML::Builder.new do |xml|
|
18
|
+
xml.request {
|
19
|
+
xml.SOSaveRq {
|
20
|
+
xml.SalesOrder {
|
21
|
+
xml.Number sales_order[:number] unless sales_order[:number].nil?
|
22
|
+
xml.Salesman sales_order[:salesman] unless sales_order[:salesman].nil?
|
23
|
+
xml.CustomerName sales_order[:customer_name] unless sales_order[:customer_name].nil?
|
24
|
+
xml.Status "10" if sales_order[:status].nil?
|
25
|
+
xml.Status sales_order[:status] unless sales_order[:status].nil?
|
26
|
+
xml.Carrier sales_order[:carrier] unless sales_order[:carrier].nil?
|
27
|
+
xml.PaymentTerms sales_order[:payment_terms] unless sales_order[:payment_terms].nil?
|
28
|
+
xml.CustomerPO sales_order[:customer_po] unless sales_order[:customer_po].nil?
|
29
|
+
xml.VendorPO sales_order[:vendor_po] unless sales_order[:vendor_po].nil?
|
30
|
+
xml.QuickBooksClassName sales_order[:quick_books_class_name] unless sales_order[:quick_books_class_name].nil?
|
31
|
+
xml.BillTo {
|
32
|
+
xml.Name sales_order[:bill_to][:name] unless sales_order[:bill_to][:name].nil?
|
33
|
+
xml.AddressField sales_order[:bill_to][:address] unless sales_order[:bill_to][:address].nil?
|
34
|
+
xml.City sales_order[:bill_to][:city] unless sales_order[:bill_to][:city].nil?
|
35
|
+
xml.Zip sales_order[:bill_to][:zip] unless sales_order[:bill_to][:zip].nil?
|
36
|
+
xml.Country sales_order[:bill_to][:country] unless sales_order[:bill_to][:country].nil?
|
37
|
+
xml.State sales_order[:bill_to][:state] unless sales_order[:bill_to][:state].nil?
|
38
|
+
}
|
39
|
+
xml.Ship {
|
40
|
+
xml.Name sales_order[:ship_to][:name] unless sales_order[:ship_to][:name].nil?
|
41
|
+
xml.AddressField sales_order[:ship_to][:address] unless sales_order[:ship_to][:address].nil?
|
42
|
+
xml.City sales_order[:ship_to][:city] unless sales_order[:ship_to][:city].nil?
|
43
|
+
xml.Zip sales_order[:ship_to][:zip] unless sales_order[:ship_to][:zip].nil?
|
44
|
+
xml.Country sales_order[:ship_to][:country] unless sales_order[:ship_to][:country].nil?
|
45
|
+
xml.State sales_order[:ship_to][:state] unless sales_order[:ship_to][:state].nil?
|
46
|
+
}
|
47
|
+
xml.CustomFields {
|
48
|
+
sales_order[:custom_fields].each do |field|
|
49
|
+
xml.CustomField {
|
50
|
+
xml.ID field[:id] unless field[:id].nil?
|
51
|
+
xml.Name field[:name] unless field[:name].nil?
|
52
|
+
xml.Type field[:type] unless field[:type].nil?
|
53
|
+
xml.Info field[:info] unless field[:info].nil?
|
54
|
+
xml.Description field[:description] unless field[:description].nil?
|
55
|
+
}
|
56
|
+
end
|
57
|
+
} unless sales_order[:custom_fields].nil?
|
58
|
+
xml.Items {
|
59
|
+
sales_order[:items].each do |item|
|
60
|
+
xml.SalesOrderItem {
|
61
|
+
xml.ID item[:id] unless item[:id].nil?
|
62
|
+
xml.ProductNumber item[:product_number] unless item[:product_number].nil?
|
63
|
+
xml.ProductPrice item[:product_price] unless item[:product_price].nil?
|
64
|
+
xml.TotalPrice item[:total_price] unless item[:total_price].nil?
|
65
|
+
xml.Quantity item[:quantity] unless item[:quantity].nil?
|
66
|
+
xml.UOMCode item[:uom_code] unless item[:uom_code].nil?
|
67
|
+
xml.Description item[:description] unless item[:description].nil?
|
68
|
+
xml.LineNumber item[:line_number] unless item[:line_number].nil?
|
69
|
+
xml.QuickBooksClassName item[:quick_books_class_name] unless item[:quick_books_class_name].nil?
|
70
|
+
xml.NewItemFlag "false"
|
71
|
+
xml.ItemType item[:item_type] || "10"
|
72
|
+
xml.Status "10"
|
73
|
+
xml.AdjustPercentage item[:adjust_percentage] unless item[:adjust_percentage].nil?
|
74
|
+
} unless sales_order[:items].nil?
|
75
|
+
end
|
76
|
+
}
|
77
|
+
}
|
78
|
+
xml.IssueFlag "false"
|
79
|
+
xml.IgnoreItems "false"
|
80
|
+
}
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fishbowl::Requests
|
2
|
+
def self.total_inventory(part_num, location_group)
|
3
|
+
raise ArgumentError if part_num.nil?
|
4
|
+
|
5
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
6
|
+
xml.request {
|
7
|
+
xml.GetTotalInventoryRq {
|
8
|
+
xml.PartNumber part_num
|
9
|
+
xml.LocationGroup location_group
|
10
|
+
}
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
code, response = Fishbowl::Objects::BaseObject.new.send_request(builder, "GetTotalInventoryRs")
|
15
|
+
|
16
|
+
response.xpath("//FbiXml/FbiMsgsRs/GetTotalInventoryRs")
|
17
|
+
end
|
18
|
+
end
|
data/lib/fishbowl/version.rb
CHANGED
data/lib/status_codes.yml
CHANGED
@@ -30,154 +30,154 @@ codes:
|
|
30
30
|
message: Unknown login error occurred.
|
31
31
|
1110:
|
32
32
|
code: 1110
|
33
|
-
message: A new Integrated Application has been added to Fishbowl Inventory. Please contact your Fishbowl Inventory Administrator to approve this Integrated Application.
|
33
|
+
message: A new Integrated Application has been added to Fishbowl Inventory. Please contact your Fishbowl Inventory Administrator to approve this Integrated Application.
|
34
34
|
1111:
|
35
35
|
code: 1111
|
36
|
-
message: This Integrated Application registration key does not match.
|
36
|
+
message: This Integrated Application registration key does not match.
|
37
37
|
1112:
|
38
38
|
code: 1112
|
39
|
-
message: This Integrated Application has not been approved by the Fishbowl Inventory Administrator.
|
39
|
+
message: This Integrated Application has not been approved by the Fishbowl Inventory Administrator.
|
40
40
|
1120:
|
41
41
|
code: 1120
|
42
|
-
message: Invalid Username or Password.
|
42
|
+
message: Invalid Username or Password.
|
43
43
|
1130:
|
44
44
|
code: 1130
|
45
|
-
message: Invalid Ticket passed to Fishbowl Inventory Server.
|
45
|
+
message: Invalid Ticket passed to Fishbowl Inventory Server.
|
46
46
|
1131:
|
47
47
|
code: 1131
|
48
|
-
message: Invalid Key value.
|
48
|
+
message: Invalid Key value.
|
49
49
|
1140:
|
50
50
|
code: 1140
|
51
|
-
message: Initialization token is not correct type.
|
51
|
+
message: Initialization token is not correct type.
|
52
52
|
1150:
|
53
53
|
code: 1150
|
54
|
-
message: Request was invalid
|
54
|
+
message: Request was invalid
|
55
55
|
1160:
|
56
56
|
code: 1160
|
57
|
-
message: Response was invalid.
|
57
|
+
message: Response was invalid.
|
58
58
|
1162:
|
59
59
|
code: 1162
|
60
|
-
message: The login limit has been reached for the server's key.
|
60
|
+
message: The login limit has been reached for the server's key.
|
61
61
|
1200:
|
62
62
|
code: 1200
|
63
|
-
message: Custom Field is invalid.
|
63
|
+
message: Custom Field is invalid.
|
64
64
|
1500:
|
65
65
|
code: 1500
|
66
|
-
message: The import was not properly formed.
|
66
|
+
message: The import was not properly formed.
|
67
67
|
1501:
|
68
68
|
code: 1501
|
69
|
-
message: That import type is not supported
|
69
|
+
message: That import type is not supported
|
70
70
|
1502:
|
71
71
|
code: 1502
|
72
|
-
message: File not found.
|
72
|
+
message: File not found.
|
73
73
|
1503:
|
74
74
|
code: 1503
|
75
|
-
message: That export type is not supported.
|
75
|
+
message: That export type is not supported.
|
76
76
|
1504:
|
77
77
|
code: 1504
|
78
|
-
message: File could not be written to.
|
78
|
+
message: File could not be written to.
|
79
79
|
1505:
|
80
80
|
code: 1505
|
81
|
-
message: The import data was of the wrong type.
|
81
|
+
message: The import data was of the wrong type.
|
82
82
|
2000:
|
83
83
|
code: 2000
|
84
|
-
message: Was not able to find the Part {0}.
|
84
|
+
message: Was not able to find the Part {0}.
|
85
85
|
2001:
|
86
86
|
code: 2001
|
87
|
-
message: The part was invalid.
|
87
|
+
message: The part was invalid.
|
88
88
|
2100:
|
89
89
|
code: 2100
|
90
|
-
message: Was not able to find the Product {0}.
|
90
|
+
message: Was not able to find the Product {0}.
|
91
91
|
2101:
|
92
92
|
code: 2101
|
93
|
-
message: The product was invalid.
|
93
|
+
message: The product was invalid.
|
94
94
|
2200:
|
95
95
|
code: 2200
|
96
|
-
message: The yield failed.
|
96
|
+
message: The yield failed.
|
97
97
|
2201:
|
98
98
|
code: 2201
|
99
|
-
message: Commit failed.
|
99
|
+
message: Commit failed.
|
100
100
|
2202:
|
101
101
|
code: 2202
|
102
|
-
message: Add initial inventory failed.
|
102
|
+
message: Add initial inventory failed.
|
103
103
|
2203:
|
104
104
|
code: 2203
|
105
|
-
message: Can not adjust committed inventory.
|
105
|
+
message: Can not adjust committed inventory.
|
106
106
|
2300:
|
107
107
|
code: 2300
|
108
|
-
message: Was not able to find the Tag number {0}.
|
108
|
+
message: Was not able to find the Tag number {0}.
|
109
109
|
2301:
|
110
110
|
code: 2301
|
111
|
-
message: The tag is invalid.
|
111
|
+
message: The tag is invalid.
|
112
112
|
2302:
|
113
113
|
code: 2302
|
114
|
-
message: The tag move failed.
|
114
|
+
message: The tag move failed.
|
115
115
|
2303:
|
116
116
|
code: 2303
|
117
|
-
message: Was not able to save Tag number {0}.
|
117
|
+
message: Was not able to save Tag number {0}.
|
118
118
|
2304:
|
119
119
|
code: 2304
|
120
|
-
message: Not enough available inventory in Tagnumber {0}.
|
120
|
+
message: Not enough available inventory in Tagnumber {0}.
|
121
121
|
2305:
|
122
122
|
code: 2305
|
123
|
-
message: Tag number {0} is a location.
|
123
|
+
message: Tag number {0} is a location.
|
124
124
|
2400:
|
125
125
|
code: 2400
|
126
|
-
message: Invalid UOM.
|
126
|
+
message: Invalid UOM.
|
127
127
|
2401:
|
128
128
|
code: 2401
|
129
|
-
message: UOM {0} not found.
|
129
|
+
message: UOM {0} not found.
|
130
130
|
2402:
|
131
131
|
code: 2402
|
132
|
-
message: Integer UOM {0} cannot have non-integer quantity.
|
132
|
+
message: Integer UOM {0} cannot have non-integer quantity.
|
133
133
|
2500:
|
134
134
|
code: 2500
|
135
|
-
message: The Tracking is not valid.
|
135
|
+
message: The Tracking is not valid.
|
136
136
|
2510:
|
137
137
|
code: 2510
|
138
|
-
message: Serial number is missing.
|
138
|
+
message: Serial number is missing.
|
139
139
|
2511:
|
140
140
|
code: 2511
|
141
|
-
message: Serial number is null.
|
141
|
+
message: Serial number is null.
|
142
142
|
2512:
|
143
143
|
code: 2512
|
144
|
-
message: Serial number is duplicate.
|
144
|
+
message: Serial number is duplicate.
|
145
145
|
2513:
|
146
146
|
code: 2513
|
147
|
-
message: Serial number is not valid.
|
147
|
+
message: Serial number is not valid.
|
148
148
|
2600:
|
149
149
|
code: 2600
|
150
|
-
message: Location not found.
|
150
|
+
message: Location not found.
|
151
151
|
2601:
|
152
152
|
code: 2601
|
153
|
-
message: Invalid location.
|
153
|
+
message: Invalid location.
|
154
154
|
2602:
|
155
155
|
code: 2602
|
156
|
-
message: Location Group {0} not found.
|
156
|
+
message: Location Group {0} not found.
|
157
157
|
3000:
|
158
158
|
code: 3000
|
159
|
-
message: Customer {0} not found.
|
159
|
+
message: Customer {0} not found.
|
160
160
|
3001:
|
161
161
|
code: 3001
|
162
|
-
message: Customer is invalid.
|
162
|
+
message: Customer is invalid.
|
163
163
|
3100:
|
164
164
|
code: 3100
|
165
|
-
message: Vendor {0} not found.
|
165
|
+
message: Vendor {0} not found.
|
166
166
|
3101:
|
167
167
|
code: 3101
|
168
|
-
message: Vendor is invalid.
|
168
|
+
message: Vendor is invalid.
|
169
169
|
4000:
|
170
170
|
code: 4000
|
171
|
-
message: There was an error load PO {0}.
|
171
|
+
message: There was an error load PO {0}.
|
172
172
|
4001:
|
173
173
|
code: 4001
|
174
|
-
message: Unknow status {0}.
|
174
|
+
message: Unknow status {0}.
|
175
175
|
4002:
|
176
176
|
code: 4002
|
177
|
-
message: Unknown carrier {0}.
|
177
|
+
message: Unknown carrier {0}.
|
178
178
|
4003:
|
179
179
|
code: 4003
|
180
|
-
message: Unknown QuickBooks class {0}.
|
180
|
+
message: Unknown QuickBooks class {0}.
|
181
181
|
4004:
|
182
182
|
code: 4004
|
183
|
-
message: PO does not have a PO number. Please turn on the auto-assign PO number option in the purchase order module options.
|
183
|
+
message: PO does not have a PO number. Please turn on the auto-assign PO number option in the purchase order module options.
|
data/spec/connection_spec.rb
CHANGED
@@ -1,99 +1,99 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Fishbowl::Connection do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
1
|
+
# require 'spec_helper'
|
2
|
+
#
|
3
|
+
# describe Fishbowl::Connection do
|
4
|
+
# before :each do
|
5
|
+
# mock_tcp_connection
|
6
|
+
# end
|
7
|
+
#
|
8
|
+
# after :each do
|
9
|
+
# unmock_tcp
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# describe '.connect' do
|
13
|
+
# it 'should require a host' do
|
14
|
+
# lambda {
|
15
|
+
# Fishbowl::Connection.connect
|
16
|
+
# }.should raise_error(Fishbowl::Errors::MissingHost)
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# it 'should default to port 28192' do
|
20
|
+
# Fishbowl::Connection.connect(host: 'localhost')
|
21
|
+
# Fishbowl::Connection.port.should eq(28192)
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# describe '.login' do
|
26
|
+
# before :each do
|
27
|
+
# Fishbowl::Connection.connect(host: 'localhost')
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# it 'should require the connection to be established' do
|
31
|
+
# lambda {
|
32
|
+
# Fishbowl::Connection.close
|
33
|
+
# Fishbowl::Connection.login
|
34
|
+
# }.should raise_error(Fishbowl::Errors::ConnectionNotEstablished)
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# it 'should require a username' do
|
38
|
+
# lambda {
|
39
|
+
# Fishbowl::Connection.login(password: 'secret')
|
40
|
+
# }.should raise_error(Fishbowl::Errors::MissingUsername)
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# it 'should require a password' do
|
44
|
+
# lambda {
|
45
|
+
# Fishbowl::Connection.login(username: 'johndoe')
|
46
|
+
# }.should raise_error(Fishbowl::Errors::MissingPassword)
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# it 'should connect to Fishbowl API' do
|
50
|
+
# mock_login_response
|
51
|
+
# Fishbowl::Connection.login(username: 'johndoe', password: 'secret')
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# describe '.close' do
|
56
|
+
# it "should close the connection" do
|
57
|
+
# lambda {
|
58
|
+
# mock_login_response
|
59
|
+
# Fishbowl::Connection.connect(host: 'localhost')
|
60
|
+
# Fishbowl::Connection.login(username: 'johndoe', password: 'secret')
|
61
|
+
#
|
62
|
+
# Fishbowl::Connection.close
|
63
|
+
# Fishbowl::Connection.login
|
64
|
+
# }.should raise_error(Fishbowl::Errors::ConnectionNotEstablished)
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# describe '.host' do
|
69
|
+
# it 'should return the host value' do
|
70
|
+
# Fishbowl::Connection.connect(host: 'localhost')
|
71
|
+
# Fishbowl::Connection.host.should eq('localhost')
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# describe '.port' do
|
76
|
+
# it "should return the port value" do
|
77
|
+
# Fishbowl::Connection.connect(host: 'localhost', port: 1234)
|
78
|
+
# Fishbowl::Connection.port.should eq(1234)
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# describe '.username' do
|
83
|
+
# it 'should return the username value' do
|
84
|
+
# mock_login_response
|
85
|
+
# Fishbowl::Connection.connect(host: 'localhost')
|
86
|
+
# Fishbowl::Connection.login(username: 'johndoe', password: 'secret')
|
87
|
+
# Fishbowl::Connection.username.should eq('johndoe')
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# describe '.password' do
|
92
|
+
# it 'should return the password value' do
|
93
|
+
# mock_login_response
|
94
|
+
# Fishbowl::Connection.connect(host: 'localhost')
|
95
|
+
# Fishbowl::Connection.login(username: 'johndoe', password: 'secret')
|
96
|
+
# Fishbowl::Connection.password.should eq('secret')
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
# end
|
data/spec/errors_spec.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
describe Fishbowl::Errors do
|
4
5
|
describe '.confirm_success_or_raise' do
|
5
6
|
it "should return true is code is 1000" do
|
6
|
-
Fishbowl::Errors.confirm_success_or_raise('1000'
|
7
|
+
expect(Fishbowl::Errors.confirm_success_or_raise('1000')).to eql true
|
7
8
|
end
|
8
9
|
|
9
|
-
it "should raise an error on any other code" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
10
|
+
# it "should raise an error on any other code" do
|
11
|
+
# statuses = YAML.load_file('./lib/status_codes.yml')['codes']
|
12
|
+
# status_codes = statuses.values.map{|sc| sc["code"]} - [1000]
|
13
|
+
# 1.times do
|
14
|
+
# code = status_codes.sample
|
15
|
+
# expect(Fishbowl::Errors.confirm_success_or_raise(code)).to raise_error(Exception.new "My error")
|
16
|
+
# # expect(Fishbowl::Errors.confirm_success_or_raise(code)).to raise_error(StatusError, status[code]['message'])
|
17
|
+
# end
|
18
|
+
# end
|
17
19
|
end
|
18
20
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,48 +1,50 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rspec'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
3
|
+
require 'fishbowl'
|
4
|
+
require 'pry'
|
5
|
+
#
|
6
|
+
# if ENV['CI'] != 'true'
|
7
|
+
# require 'spork'
|
8
|
+
#
|
9
|
+
# Spork.prefork do
|
10
|
+
# unless ENV['DRB']
|
11
|
+
# require 'simplecov'
|
12
|
+
# SimpleCov.start do
|
13
|
+
# add_filter "/spec/"
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# require 'fishbowl'
|
18
|
+
#
|
19
|
+
# require 'equivalent-xml/rspec_matchers'
|
20
|
+
#
|
21
|
+
# require 'support/examples_loader'
|
22
|
+
# require 'support/fake_socket'
|
23
|
+
# require 'support/response_mocks'
|
24
|
+
#
|
25
|
+
# RSpec.configure do |config|
|
26
|
+
# # some (optional) config here
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# Spork.each_run do
|
31
|
+
# if ENV['DRB']
|
32
|
+
# require 'simplecov'
|
33
|
+
# SimpleCov.start do
|
34
|
+
# add_filter "/spec/"
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
# else
|
39
|
+
# require 'fishbowl'
|
40
|
+
#
|
41
|
+
# require 'equivalent-xml/rspec_matchers'
|
42
|
+
#
|
43
|
+
# require 'support/examples_loader'
|
44
|
+
# require 'support/fake_socket'
|
45
|
+
# require 'support/response_mocks'
|
46
|
+
#
|
47
|
+
# RSpec.configure do |config|
|
48
|
+
# # some (optional) config here
|
49
|
+
# end
|
50
|
+
# end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fishbowl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Thompson, Simeon Berns
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.8.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.8.5
|
27
27
|
description: Provides an interface to the Fishbowl Inventory API
|
28
28
|
email:
|
29
29
|
- james@plainprograms.com, simeonberns@gmail.com
|
@@ -31,10 +31,10 @@ executables: []
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
-
- .gitignore
|
35
|
-
- .rspec
|
36
|
-
- .rvmrc
|
37
|
-
- .travis.yml
|
34
|
+
- ".gitignore"
|
35
|
+
- ".rspec"
|
36
|
+
- ".rvmrc"
|
37
|
+
- ".travis.yml"
|
38
38
|
- Gemfile
|
39
39
|
- Guardfile
|
40
40
|
- LICENSE.txt
|
@@ -67,10 +67,16 @@ files:
|
|
67
67
|
- lib/fishbowl/requests/get_import_list.rb
|
68
68
|
- lib/fishbowl/requests/get_location_group_list.rb
|
69
69
|
- lib/fishbowl/requests/get_location_list.rb
|
70
|
+
- lib/fishbowl/requests/get_product.rb
|
71
|
+
- lib/fishbowl/requests/get_product_price.rb
|
70
72
|
- lib/fishbowl/requests/get_uom_list.rb
|
71
73
|
- lib/fishbowl/requests/get_vendor_list.rb
|
72
74
|
- lib/fishbowl/requests/get_vendor_name_list.rb
|
73
75
|
- lib/fishbowl/requests/get_work_order_list.rb
|
76
|
+
- lib/fishbowl/requests/inventory_quantity.rb
|
77
|
+
- lib/fishbowl/requests/load_sales_order.rb
|
78
|
+
- lib/fishbowl/requests/save_sales_order.rb
|
79
|
+
- lib/fishbowl/requests/total_inventory.rb
|
74
80
|
- lib/fishbowl/requests/void_sales_order.rb
|
75
81
|
- lib/fishbowl/version.rb
|
76
82
|
- lib/status_codes.yml
|
@@ -203,7 +209,7 @@ files:
|
|
203
209
|
- spec/support/examples_loader.rb
|
204
210
|
- spec/support/fake_socket.rb
|
205
211
|
- spec/support/response_mocks.rb
|
206
|
-
homepage: https://github.com/
|
212
|
+
homepage: https://github.com/zion/fishbowl
|
207
213
|
licenses: []
|
208
214
|
metadata: {}
|
209
215
|
post_install_message:
|
@@ -212,17 +218,17 @@ require_paths:
|
|
212
218
|
- lib
|
213
219
|
required_ruby_version: !ruby/object:Gem::Requirement
|
214
220
|
requirements:
|
215
|
-
- -
|
221
|
+
- - ">="
|
216
222
|
- !ruby/object:Gem::Version
|
217
223
|
version: '0'
|
218
224
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
219
225
|
requirements:
|
220
|
-
- -
|
226
|
+
- - ">="
|
221
227
|
- !ruby/object:Gem::Version
|
222
228
|
version: '0'
|
223
229
|
requirements: []
|
224
230
|
rubyforge_project:
|
225
|
-
rubygems_version: 2.
|
231
|
+
rubygems_version: 2.7.7
|
226
232
|
signing_key:
|
227
233
|
specification_version: 4
|
228
234
|
summary: Fishbowl Inventory API
|