whiplash_api 0.1.1 → 1.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 +11 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +18 -17
- data/{README.rdoc → README.md} +38 -15
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/whiplash_api +7 -0
- data/lib/whiplash_api.rb +6 -3
- data/lib/whiplash_api/base.rb +36 -40
- data/lib/whiplash_api/cli.rb +49 -0
- data/lib/whiplash_api/connection.rb +26 -0
- data/lib/whiplash_api/item.rb +49 -7
- data/lib/whiplash_api/order.rb +127 -8
- data/lib/whiplash_api/order_item.rb +44 -5
- data/lib/whiplash_api/shipnotice.rb +68 -0
- data/lib/whiplash_api/shipnotice_item.rb +39 -0
- data/lib/whiplash_api/version.rb +3 -0
- data/whiplash_api.gemspec +30 -0
- metadata +130 -141
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 74a85dbf10a36892fe32bd9e139c24c224e8f646
|
4
|
+
data.tar.gz: 098b22a96b9eb3b97473feb2c5731cfdfb2f6261
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 838992e0107a5a1f879e36310b758769260b480696e1bf94fd3f5986218b1169ed7b63d1a084c14096a34260433828d450827cf7e985b6d6b53c2211d1adff0f
|
7
|
+
data.tar.gz: 0ea784819cc42c368884c4ae1093d032064edf2ee4b50fa4f054155655825a4f6d28c08819166ad6e7cac5b8cc1e50a1667c1b0f4a083b23ce4339a0b61c0dc7
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
CHANGED
@@ -1,20 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
3
|
+
Copyright (c) 2015 Nikhil Gupta
|
10
4
|
|
11
|
-
|
12
|
-
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,22 +1,26 @@
|
|
1
1
|
Whiplash API V1 - Ruby Client
|
2
2
|
================================
|
3
3
|
|
4
|
-
|
4
|
+
[![Build Status](https://travis-ci.org/nikhgupta/whiplash_api.svg?branch=master)](https://travis-ci.org/nikhgupta/whiplash_api)
|
5
5
|
|
6
|
-
|
6
|
+
This library provides a wrapper around the [Whiplash][whiplash] [Merchandising REST API][api] for use within Ruby apps or via the console.
|
7
7
|
|
8
|
-
|
8
|
+
### Note
|
9
9
|
|
10
|
-
|
10
|
+
**If you are using a Rails app, the advised approach is to use ActiveResource. You can get started or gain inspiration from our [example Rails app][app]: **
|
11
11
|
|
12
|
-
|
12
|
+
### Requirements
|
13
|
+
|
14
|
+
- Ruby 1.9.3+
|
13
15
|
- Rubygems
|
14
16
|
- JSON
|
15
17
|
- ActiveResource
|
16
18
|
|
17
19
|
A valid API key is required to authenticate requests. You can find your API key on your customer account page.
|
18
20
|
|
19
|
-
|
21
|
+
You can, also, use the test API key `Hc2BHTn3bcrwyPooyYTP` to test this client.
|
22
|
+
|
23
|
+
### Installation
|
20
24
|
|
21
25
|
```
|
22
26
|
gem install whiplash_api
|
@@ -28,7 +32,7 @@ Or if you're using Bundler:
|
|
28
32
|
gem 'whiplash_api'
|
29
33
|
```
|
30
34
|
|
31
|
-
|
35
|
+
### Configuration
|
32
36
|
|
33
37
|
To use the API client in your Ruby code, provide the required credentials as follows:
|
34
38
|
|
@@ -36,22 +40,27 @@ To use the API client in your Ruby code, provide the required credentials as fol
|
|
36
40
|
require 'rubygems'
|
37
41
|
require 'whiplash_api'
|
38
42
|
|
39
|
-
|
43
|
+
WhiplashAPI::Base.api_key = 'XXXXXXXXXXXXX'
|
40
44
|
```
|
45
|
+
|
46
|
+
An error will be raised if no API key is provided.
|
47
|
+
|
41
48
|
You'll likely want to start by testing in the Sandbox:
|
42
49
|
|
43
50
|
```
|
44
|
-
|
51
|
+
WhiplashAPI::Base.testing!
|
45
52
|
```
|
46
53
|
|
47
|
-
|
54
|
+
You can, also, check a very basic implementation/example inside `exe/whiplash_api` file.
|
55
|
+
|
56
|
+
### Usage
|
48
57
|
|
49
|
-
The API currently gives you access to
|
58
|
+
The API currently gives you access to all endpoints supported by [Whiplash][whiplash] [Merchandising API][api].
|
50
59
|
|
51
60
|
```
|
52
61
|
$ irb
|
53
62
|
>
|
54
|
-
>
|
63
|
+
> WhiplashAPI::Base.api_key = 'XXXXXXXXXXXXX'
|
55
64
|
>
|
56
65
|
> items = WhiplashAPI::Item.all
|
57
66
|
>
|
@@ -59,13 +68,13 @@ $ irb
|
|
59
68
|
>
|
60
69
|
> order = WhiplashAPI::Order.last
|
61
70
|
>
|
62
|
-
> orders = WhiplashAPI::Order.status
|
71
|
+
> orders = WhiplashAPI::Order.all(:params => {:status => 'shipped', :created_at_min => '2008-01-01'})
|
63
72
|
>
|
64
73
|
> order_item = WhiplashAPI::OrderItem.originator(ID_IN_YOUR_STORE)
|
65
74
|
>
|
66
75
|
```
|
67
76
|
|
68
|
-
|
77
|
+
### Contributing to the Whiplash API Gem
|
69
78
|
|
70
79
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
71
80
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
@@ -75,7 +84,21 @@ $ irb
|
|
75
84
|
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
76
85
|
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
77
86
|
|
78
|
-
|
87
|
+
### Testing Whiplash API Gem
|
88
|
+
|
89
|
+
You can run the tests on the current version of this gem, by cloning it locally, and then, running:
|
90
|
+
|
91
|
+
```
|
92
|
+
WL_KEY=Hc2BHTn3bcrwyPooyYTP rspec spec
|
93
|
+
```
|
94
|
+
|
95
|
+
Note that, testing can take a long time, since tests are performed directly on the testing server, and no mocks are used. This is to ensure that the API conforms to the tests, at the same time.
|
96
|
+
|
97
|
+
### Copyright
|
79
98
|
|
80
99
|
Copyright (c) 2012 Whiplash Merchandising/Mark Dickson. See LICENSE.txt for further details.
|
81
100
|
|
101
|
+
|
102
|
+
[whiplash]: https://www.whiplashmerch.com/
|
103
|
+
[api]: https://www.whiplashmerch.com/developers/api
|
104
|
+
[app]: https://github.com/ideaoforder/whiplash-rails-example
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "whiplash_api"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/exe/whiplash_api
ADDED
data/lib/whiplash_api.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
require "
|
2
|
-
require
|
1
|
+
require "active_resource"
|
2
|
+
require "whiplash_api/version"
|
3
3
|
|
4
4
|
require 'whiplash_api/base'
|
5
|
+
require 'whiplash_api/connection'
|
5
6
|
require 'whiplash_api/item'
|
6
7
|
require 'whiplash_api/order'
|
7
|
-
require 'whiplash_api/order_item'
|
8
|
+
require 'whiplash_api/order_item'
|
9
|
+
require 'whiplash_api/shipnotice'
|
10
|
+
require 'whiplash_api/shipnotice_item'
|
data/lib/whiplash_api/base.rb
CHANGED
@@ -1,54 +1,50 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
# def reserved(*names)
|
5
|
-
# class_variable_set(:@@reserved, names.collect{|x| x.to_s})
|
6
|
-
# end
|
1
|
+
module WhiplashApi
|
2
|
+
class Error < ::StandardError; end
|
3
|
+
class RecordNotFound < Error; end
|
7
4
|
|
8
5
|
class Base < ActiveResource::Base
|
9
|
-
|
10
|
-
|
11
|
-
self.site = 'https://www.whiplashmerch.com/api/'
|
6
|
+
self.site = 'https://www.whiplashmerch.com/api/'
|
12
7
|
self.format = :json
|
13
|
-
|
14
|
-
# Thanks to Brandon Keepers for this little nugget:
|
15
|
-
# http://opensoul.org/blog/archives/2010/02/16/active-resource-in-practice/
|
8
|
+
|
16
9
|
class << self
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
else
|
25
|
-
@headers ||= {}
|
26
|
-
end
|
10
|
+
def testing!
|
11
|
+
self.site = 'http://testing.whiplashmerch.com/api/'
|
12
|
+
|
13
|
+
ActiveSupport::Notifications.subscribe("request.active_resource") do |*args|
|
14
|
+
puts "[ActiveResource] Request: #{args.last[:request_uri]}"
|
15
|
+
puts "[ActiveResource] Response: #{args.last[:result].body}"
|
16
|
+
end if ENV['DEBUG'].present?
|
27
17
|
end
|
28
|
-
|
18
|
+
|
19
|
+
# Override the connection that ActiveResource uses, so that we can add our
|
20
|
+
# own error messages for the weird cases when API returns 422 error.
|
21
|
+
def connection(refresh = false)
|
22
|
+
message = "You must set a valid API Key. Current: #{headers['X-API-KEY'].inspect}"
|
23
|
+
raise WhiplashApi::Error, message if headers['X-API-KEY'].blank?
|
24
|
+
@connection = WhiplashApi::Connection.new(site, format) if refresh || @connection.nil?
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
29
28
|
def api_key=(api_key)
|
30
29
|
headers['X-API-KEY'] = api_key
|
31
30
|
end
|
32
|
-
|
31
|
+
|
33
32
|
def api_version=(v)
|
34
33
|
headers['X-API-VERSION'] = v
|
35
34
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def sanitize_as_resource(collection)
|
39
|
+
return collection if collection.blank?
|
40
|
+
as_array = collection.is_a?(Array)
|
41
|
+
collection = [collection].flatten.map do |resource|
|
42
|
+
resource = self.new(resource)
|
43
|
+
resource.instance_variable_set("@persisted", true)
|
44
|
+
resource
|
45
|
+
end
|
46
|
+
as_array ? collection : collection.first
|
43
47
|
end
|
44
|
-
|
45
48
|
end
|
46
|
-
|
47
|
-
# Example Instance Method
|
48
|
-
# def class_name
|
49
|
-
# self.class.name.split('::').last.downcase
|
50
|
-
# end
|
51
|
-
|
52
49
|
end
|
53
|
-
|
54
|
-
end
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
# An example implementation of this gem.
|
4
|
+
module WhiplashApi
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
class_option :test, boolean: true, desc: "run using test API endpoints."
|
8
|
+
class_option :local, boolean: true, desc: "run using localhost API endpoints."
|
9
|
+
|
10
|
+
desc "list [API_KEY]", "Fetch items for the current account"
|
11
|
+
def list(api_key = nil)
|
12
|
+
setup! api_key
|
13
|
+
|
14
|
+
items = WhiplashApi::Item.all
|
15
|
+
items.each do |item|
|
16
|
+
message = "%16s" % item.sku
|
17
|
+
message += "%20s" % item.description
|
18
|
+
message += " %3s " % (item.available ? "Yes" : "No")
|
19
|
+
message += item.title
|
20
|
+
say_status "Product", message
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "sku ID [API_KEY]", "Fetch item by SKU"
|
25
|
+
def sku(id, api_key = nil)
|
26
|
+
setup! api_key
|
27
|
+
|
28
|
+
item = WhiplashApi::Item.sku id
|
29
|
+
message = "%16s" % item.sku
|
30
|
+
message += "%20s" % item.description
|
31
|
+
message += " %3s " % (item.available ? "Yes" : "No")
|
32
|
+
message += item.title
|
33
|
+
say_status "Product", message
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "test", "test"
|
37
|
+
def test
|
38
|
+
setup!
|
39
|
+
binding.pry
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def setup!(api_key = nil)
|
45
|
+
WhiplashApi::Base.api_key = api_key || ENV['WL_KEY']
|
46
|
+
WhiplashApi::Base.testing! if ENV['API_ENV'] == "test" || options[:test]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module WhiplashApi
|
2
|
+
class Connection < ActiveResource::Connection
|
3
|
+
private
|
4
|
+
|
5
|
+
def request(*arguments)
|
6
|
+
super
|
7
|
+
rescue ActiveResource::ResourceInvalid => e
|
8
|
+
data = JSON.parse e.response.body
|
9
|
+
case
|
10
|
+
when data['error'].present? && data['error'].downcase =~ /record.*not.*found/
|
11
|
+
raise WhiplashApi::RecordNotFound
|
12
|
+
when data['error'].present?
|
13
|
+
raise WhiplashApi::Error, data['error'].humanize
|
14
|
+
when data['errors'].present? && data['errors']['base'].present?
|
15
|
+
messages = data['errors']['base']
|
16
|
+
raise WhiplashApi::Error, "Errors were encountered while creating the resource.\n- #{messages.join("\n- ")}"
|
17
|
+
when data['errors'].present?
|
18
|
+
messages = data['errors'].map{|k,v| v.map{|message| "#{k.humanize} #{message}"}}.flatten
|
19
|
+
raise WhiplashApi::Error, "Errors were encountered while creating the resource.\n- #{messages.join("\n- ")}"
|
20
|
+
else
|
21
|
+
raise WhiplashApi::Error, "Errors were encountered while creating the resource.\nResponse was: #{e.response.body}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
data/lib/whiplash_api/item.rb
CHANGED
@@ -1,15 +1,57 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module WhiplashApi
|
3
2
|
class Item < Base
|
4
3
|
class << self
|
4
|
+
def count(args={})
|
5
|
+
self.get(:count, args)
|
6
|
+
end
|
7
|
+
|
5
8
|
def sku(sku, args={})
|
6
|
-
self.get(:sku, {:sku
|
9
|
+
sanitize_as_resource self.get(:sku, { sku: sku }.merge(args))
|
7
10
|
end
|
8
|
-
|
11
|
+
|
12
|
+
def group(id, args={})
|
13
|
+
sanitize_as_resource self.get("group/#{id}", args)
|
14
|
+
end
|
15
|
+
|
9
16
|
def originator(id, args={})
|
10
|
-
self.get(
|
17
|
+
sanitize_as_resource self.get("originator/#{id}", args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_or_create(id, args={})
|
21
|
+
self.find(id)
|
22
|
+
rescue WhiplashApi::RecordNotFound
|
23
|
+
create(args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_or_create_by_sku(sku, args={})
|
27
|
+
first_by_sku(sku) || create(args.merge(sku: sku))
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_or_create_by_originator_id(id, args={})
|
31
|
+
originator(id) || create(args.merge(originator_id: id))
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(args={})
|
35
|
+
item = self.originator(args[:originator_id])
|
36
|
+
raise RecordNotFound, "No item was found with given Originator ID." unless item
|
37
|
+
item.update_attributes(args) ? item : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(*args)
|
41
|
+
super
|
42
|
+
rescue WhiplashApi::RecordNotFound
|
43
|
+
raise RecordNotFound, "No Item was found with given ID."
|
44
|
+
end
|
45
|
+
|
46
|
+
# additional useful methods:
|
47
|
+
def first_by_sku(sku, args={})
|
48
|
+
self.sku(sku, args).first
|
11
49
|
end
|
12
50
|
end
|
13
|
-
end
|
14
51
|
|
15
|
-
|
52
|
+
# instance methods
|
53
|
+
def destroy(args={})
|
54
|
+
self.class.delete(self.id, args)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/whiplash_api/order.rb
CHANGED
@@ -1,15 +1,134 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module WhiplashApi
|
3
2
|
class Order < Base
|
4
3
|
class << self
|
5
|
-
def
|
6
|
-
|
4
|
+
def status_for(status)
|
5
|
+
status_mapping[status].to_s.titleize
|
7
6
|
end
|
8
|
-
|
7
|
+
def status_code_for(status)
|
8
|
+
status_mapping.invert[status.to_s.underscore.to_sym]
|
9
|
+
end
|
10
|
+
|
11
|
+
def count(args={})
|
12
|
+
self.get(:count, args)
|
13
|
+
end
|
14
|
+
|
9
15
|
def originator(id, args={})
|
10
|
-
self.get(
|
16
|
+
sanitize_as_resource self.get("originator/#{id}", args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_or_create_by_originator_id(id, args={})
|
20
|
+
originator(id) || create(args.merge(originator_id: id))
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(args={})
|
24
|
+
order = self.originator(args[:originator_id])
|
25
|
+
raise RecordNotFound, "No order found with given Originator ID." unless order
|
26
|
+
order.update_attributes(args) ? order : false
|
27
|
+
end
|
28
|
+
|
29
|
+
def pause(id, args={})
|
30
|
+
self.put("#{id}/pause")
|
31
|
+
end
|
32
|
+
|
33
|
+
def release(id, args={})
|
34
|
+
self.put("#{id}/release")
|
35
|
+
end
|
36
|
+
|
37
|
+
def cancel(id, args={})
|
38
|
+
self.put("#{id}/cancel")
|
39
|
+
end
|
40
|
+
|
41
|
+
def uncancel(id, args={})
|
42
|
+
self.put("#{id}/uncancel")
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def status_mapping
|
48
|
+
{
|
49
|
+
35 => :quote,
|
50
|
+
40 => :cancelled,
|
51
|
+
45 => :closed_by_originator,
|
52
|
+
50 => :unpaid,
|
53
|
+
75 => :pending_return,
|
54
|
+
77 => :return_verified,
|
55
|
+
80 => :items_unavailable,
|
56
|
+
90 => :paused,
|
57
|
+
95 => :unassignable,
|
58
|
+
100 => :processing,
|
59
|
+
120 => :printed,
|
60
|
+
150 => :picked,
|
61
|
+
155 => :prepacking_in_progress,
|
62
|
+
160 => :packed,
|
63
|
+
200 => :label_scheduled_for_purchase,
|
64
|
+
250 => :label_purchased,
|
65
|
+
300 => :shipped,
|
66
|
+
350 => :delivered,
|
67
|
+
400 => :returned_undeliverable,
|
68
|
+
410 => :replacement_requested,
|
69
|
+
430 => :exchanged,
|
70
|
+
450 => :refund_requested
|
71
|
+
}
|
11
72
|
end
|
12
73
|
end
|
13
|
-
end
|
14
74
|
|
15
|
-
|
75
|
+
# instance methods
|
76
|
+
|
77
|
+
def unshipped?
|
78
|
+
self.status.to_i < 300
|
79
|
+
end
|
80
|
+
|
81
|
+
def paused?
|
82
|
+
self.status.to_i == 90
|
83
|
+
end
|
84
|
+
|
85
|
+
def cancelled?
|
86
|
+
self.status.to_i == 40
|
87
|
+
end
|
88
|
+
|
89
|
+
def unprocessed?
|
90
|
+
self.status.to_i < 100
|
91
|
+
end
|
92
|
+
|
93
|
+
def being_processed?
|
94
|
+
self.status.to_i == 100
|
95
|
+
end
|
96
|
+
alias :processing? :being_processed?
|
97
|
+
|
98
|
+
def pause
|
99
|
+
self.put(:pause)
|
100
|
+
end
|
101
|
+
|
102
|
+
def release
|
103
|
+
self.put(:release)
|
104
|
+
end
|
105
|
+
|
106
|
+
def cancel
|
107
|
+
self.put(:cancel)
|
108
|
+
end
|
109
|
+
|
110
|
+
def uncancel
|
111
|
+
self.put(:uncancel)
|
112
|
+
end
|
113
|
+
|
114
|
+
# def pause
|
115
|
+
# self.put(:pause) and return if unshipped?
|
116
|
+
# raise Error, "Orders may only be paused before they have been shipped."
|
117
|
+
# end
|
118
|
+
|
119
|
+
# def release
|
120
|
+
# self.put(:release) and return if paused?
|
121
|
+
# raise Error, "Cannot release an order that has not been paused."
|
122
|
+
# end
|
123
|
+
|
124
|
+
# def cancel
|
125
|
+
# self.put(:cancel) and return if unshipped?
|
126
|
+
# raise Error, "Orders may only be cancelled before they have been shipped."
|
127
|
+
# end
|
128
|
+
|
129
|
+
# def uncancel
|
130
|
+
# self.put(:uncancel) and return if cancelled?
|
131
|
+
# raise Error, "Cannot uncancel an order that has not been cancelled."
|
132
|
+
# end
|
133
|
+
end
|
134
|
+
end
|
@@ -1,11 +1,50 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module WhiplashApi
|
3
2
|
class OrderItem < Base
|
4
3
|
class << self
|
4
|
+
|
5
|
+
# Finders for OrderItem require `order_id` key to be present.
|
6
|
+
# The following routine enforces this condition.
|
7
|
+
#
|
8
|
+
def find(*args)
|
9
|
+
scope = args.slice!(0)
|
10
|
+
options = args.slice!(0) || {}
|
11
|
+
|
12
|
+
if [:all, :first, :last, :one].include?(scope)
|
13
|
+
invalid = options[:params].to_s.empty? || options[:params][:order_id].to_s.empty?
|
14
|
+
raise Error, "You must supply an Order ID (as parameter) to retrieve order items for." if invalid
|
15
|
+
end
|
16
|
+
|
17
|
+
super(scope, options)
|
18
|
+
end
|
19
|
+
|
5
20
|
def originator(id, args={})
|
6
|
-
self.
|
21
|
+
self.collection_name = "order_items/originator"
|
22
|
+
order = self.find(id, args) rescue nil
|
23
|
+
self.collection_name = "order_items"
|
24
|
+
order
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_or_create_by_originator_id(id, args={})
|
28
|
+
originator(id) || create(args.merge(originator_id: id))
|
29
|
+
end
|
30
|
+
|
31
|
+
def update(id, args={})
|
32
|
+
response = self.put(id, {}, args.to_json)
|
33
|
+
response.code.to_i >= 200 && response.code.to_i < 300
|
34
|
+
rescue WhiplashApi::RecordNotFound
|
35
|
+
raise RecordNotFound, "No order item found with given ID."
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete(*args)
|
39
|
+
super
|
40
|
+
rescue WhiplashApi::RecordNotFound
|
41
|
+
raise RecordNotFound, "No order item was found with given ID."
|
7
42
|
end
|
8
43
|
end
|
9
|
-
end
|
10
44
|
|
11
|
-
|
45
|
+
# instance methods
|
46
|
+
def destroy
|
47
|
+
self.class.delete(self.id)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module WhiplashApi
|
2
|
+
class Shipnotice < Base
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def status_for(status_code)
|
6
|
+
status_mapping[status_code].to_s.titleize
|
7
|
+
end
|
8
|
+
def status_code_for(status)
|
9
|
+
status_mapping.invert[status.to_s.underscore.to_sym]
|
10
|
+
end
|
11
|
+
|
12
|
+
def warehouse_for(warehouse_code)
|
13
|
+
warehouse_mapping[warehouse_code].to_s.titleize
|
14
|
+
end
|
15
|
+
def warehouse_code_for(warehouse)
|
16
|
+
warehouse_mapping.invert[warehouse]
|
17
|
+
end
|
18
|
+
|
19
|
+
def count(args={})
|
20
|
+
self.get(:count, args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(id, args={})
|
24
|
+
response = self.put(id, {}, args.to_json)
|
25
|
+
response.code.to_i >= 200 && response.code.to_i < 300
|
26
|
+
rescue WhiplashApi::RecordNotFound
|
27
|
+
raise RecordNotFound, "No Shipment notice found with given ID."
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete(*args)
|
31
|
+
super
|
32
|
+
rescue WhiplashApi::RecordNotFound
|
33
|
+
raise RecordNotFound, "No Shipment notice found with given ID."
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def status_mapping
|
39
|
+
{
|
40
|
+
25 => :unexpected,
|
41
|
+
50 => :draft,
|
42
|
+
100 => :in_transit,
|
43
|
+
150 => :arrived,
|
44
|
+
200 => :processing,
|
45
|
+
250 => :problem,
|
46
|
+
300 => :completed,
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def warehouse_mapping
|
51
|
+
{ 1 => "Ann Arbor", 2 => "San Francisco", 3 => "London" }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# instance methods
|
56
|
+
def received?
|
57
|
+
self.status.to_i > 100
|
58
|
+
end
|
59
|
+
|
60
|
+
def processed?
|
61
|
+
self.status.to_i > 200
|
62
|
+
end
|
63
|
+
|
64
|
+
def destroy
|
65
|
+
self.class.delete(self.id)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module WhiplashApi
|
2
|
+
class ShipnoticeItem < Base
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Finders for ShipnoticeItem require `shipnotice_id` key to be present.
|
6
|
+
# The following routine enforces this condition.
|
7
|
+
#
|
8
|
+
def find(*args)
|
9
|
+
scope = args.slice!(0)
|
10
|
+
options = args.slice!(0) || {}
|
11
|
+
|
12
|
+
if [:all, :first, :last, :one].include?(scope)
|
13
|
+
invalid = options[:params].to_s.empty? || options[:params][:shipnotice_id].to_s.empty?
|
14
|
+
raise Error, "You must supply a Shipment Notice ID (as parameter) to retrieve shipnotice items for." if invalid
|
15
|
+
end
|
16
|
+
|
17
|
+
super(scope, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def update(id, args={})
|
21
|
+
response = self.put(id, {}, args.to_json)
|
22
|
+
response.code.to_i >= 200 && response.code.to_i < 300
|
23
|
+
rescue WhiplashApi::RecordNotFound
|
24
|
+
raise RecordNotFound, "No shipnotice item found with given ID."
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(*args)
|
28
|
+
super
|
29
|
+
rescue WhiplashApi::RecordNotFound
|
30
|
+
raise RecordNotFound, "No shipnotice item found with given ID."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# instance methods
|
35
|
+
def destroy
|
36
|
+
self.class.delete(self.id)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'whiplash_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "whiplash_api"
|
8
|
+
spec.version = WhiplashApi::VERSION
|
9
|
+
spec.authors = ["Mark Dickson"]
|
10
|
+
spec.email = ["mark@sitesteaders.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby Gem for connecting to the Whiplash Merchandising API}
|
13
|
+
spec.description = %q{Ruby Gem for connecting to the Whiplash Merchandising API}
|
14
|
+
spec.homepage = "http://github.com/ideaoforder/whiplash_api"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
|
27
|
+
spec.add_dependency "thor"
|
28
|
+
spec.add_dependency "activesupport"
|
29
|
+
spec.add_dependency "activeresource", "~> 4.0.0"
|
30
|
+
end
|
metadata
CHANGED
@@ -1,175 +1,164 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: whiplash_api
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease: false
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 1
|
10
|
-
segments_generated: true
|
11
|
-
version: 0.1.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.3
|
12
5
|
platform: ruby
|
13
|
-
authors:
|
6
|
+
authors:
|
14
7
|
- Mark Dickson
|
15
8
|
autorequire:
|
16
|
-
bindir:
|
9
|
+
bindir: exe
|
17
10
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
date: 2015-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
23
21
|
prerelease: false
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
version: 2.3.5
|
38
|
-
requirement: *id001
|
39
|
-
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
40
35
|
prerelease: false
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
46
45
|
- - ">="
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
|
49
|
-
segments:
|
50
|
-
- 2
|
51
|
-
- 3
|
52
|
-
- 5
|
53
|
-
segments_generated: true
|
54
|
-
version: 2.3.5
|
55
|
-
requirement: *id002
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
prerelease: false
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
58
48
|
type: :development
|
59
|
-
name: rdoc
|
60
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
|
-
requirements:
|
63
|
-
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
hash: 31
|
66
|
-
segments:
|
67
|
-
- 3
|
68
|
-
- 12
|
69
|
-
segments_generated: true
|
70
|
-
version: "3.12"
|
71
|
-
requirement: *id003
|
72
|
-
- !ruby/object:Gem::Dependency
|
73
49
|
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
74
62
|
type: :development
|
75
|
-
name: bundler
|
76
|
-
version_requirements: &id004 !ruby/object:Gem::Requirement
|
77
|
-
none: false
|
78
|
-
requirements:
|
79
|
-
- - ~>
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
hash: 23
|
82
|
-
segments:
|
83
|
-
- 1
|
84
|
-
- 0
|
85
|
-
- 0
|
86
|
-
segments_generated: true
|
87
|
-
version: 1.0.0
|
88
|
-
requirement: *id004
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
63
|
prerelease: false
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
version: 1.8.4
|
105
|
-
requirement: *id005
|
106
|
-
- !ruby/object:Gem::Dependency
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
107
77
|
prerelease: false
|
108
|
-
|
109
|
-
|
110
|
-
version_requirements: &id006 !ruby/object:Gem::Requirement
|
111
|
-
none: false
|
112
|
-
requirements:
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
113
80
|
- - ">="
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activesupport
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activeresource
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 4.0.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 4.0.0
|
121
111
|
description: Ruby Gem for connecting to the Whiplash Merchandising API
|
122
|
-
email:
|
123
|
-
|
124
|
-
|
112
|
+
email:
|
113
|
+
- mark@sitesteaders.com
|
114
|
+
executables:
|
115
|
+
- whiplash_api
|
125
116
|
extensions: []
|
126
|
-
|
127
|
-
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rspec"
|
121
|
+
- ".travis.yml"
|
122
|
+
- Gemfile
|
128
123
|
- LICENSE.txt
|
129
|
-
- README.
|
130
|
-
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- bin/console
|
127
|
+
- bin/setup
|
128
|
+
- exe/whiplash_api
|
131
129
|
- lib/whiplash_api.rb
|
132
130
|
- lib/whiplash_api/base.rb
|
131
|
+
- lib/whiplash_api/cli.rb
|
132
|
+
- lib/whiplash_api/connection.rb
|
133
133
|
- lib/whiplash_api/item.rb
|
134
134
|
- lib/whiplash_api/order.rb
|
135
135
|
- lib/whiplash_api/order_item.rb
|
136
|
-
-
|
137
|
-
-
|
138
|
-
|
136
|
+
- lib/whiplash_api/shipnotice.rb
|
137
|
+
- lib/whiplash_api/shipnotice_item.rb
|
138
|
+
- lib/whiplash_api/version.rb
|
139
|
+
- whiplash_api.gemspec
|
139
140
|
homepage: http://github.com/ideaoforder/whiplash_api
|
140
|
-
licenses:
|
141
|
+
licenses:
|
141
142
|
- MIT
|
143
|
+
metadata: {}
|
142
144
|
post_install_message:
|
143
145
|
rdoc_options: []
|
144
|
-
|
145
|
-
require_paths:
|
146
|
+
require_paths:
|
146
147
|
- lib
|
147
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
-
|
149
|
-
requirements:
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
150
|
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
segments_generated: true
|
156
|
-
version: "0"
|
157
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
-
none: false
|
159
|
-
requirements:
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
160
155
|
- - ">="
|
161
|
-
- !ruby/object:Gem::Version
|
162
|
-
|
163
|
-
segments:
|
164
|
-
- 0
|
165
|
-
segments_generated: true
|
166
|
-
version: "0"
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
167
158
|
requirements: []
|
168
|
-
|
169
159
|
rubyforge_project:
|
170
|
-
rubygems_version:
|
160
|
+
rubygems_version: 2.4.8
|
171
161
|
signing_key:
|
172
|
-
specification_version:
|
162
|
+
specification_version: 4
|
173
163
|
summary: Ruby Gem for connecting to the Whiplash Merchandising API
|
174
164
|
test_files: []
|
175
|
-
|