pwinty 1.1.0 → 3.0.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/.gitignore +12 -5
- data/.rspec +3 -0
- data/.travis.yml +22 -4
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +97 -0
- data/LICENSE.txt +21 -0
- data/README.md +208 -60
- data/Rakefile +3 -8
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/pwinty.rb +47 -73
- data/lib/pwinty/base.rb +12 -0
- data/lib/pwinty/country.rb +12 -0
- data/lib/pwinty/http_errors.rb +13 -0
- data/lib/pwinty/image.rb +24 -0
- data/lib/pwinty/order.rb +110 -0
- data/lib/pwinty/order_status.rb +17 -0
- data/lib/pwinty/photo_status.rb +8 -0
- data/lib/pwinty/shipment.rb +14 -0
- data/lib/pwinty/shipping_info.rb +9 -0
- data/lib/pwinty/version.rb +1 -1
- data/pwinty.gemspec +34 -19
- metadata +141 -35
- data/CHANGELOG.md +0 -10
- data/CONTRIBUTING.md +0 -18
- data/lib/multipart.rb +0 -76
- data/test/test_client.rb +0 -117
- data/test/test_helper.rb +0 -5
data/Rakefile
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
2
3
|
|
3
|
-
|
4
|
-
require 'rake/testtask'
|
5
|
-
|
6
|
-
Rake::TestTask.new do |t|
|
7
|
-
t.libs << 'test'
|
8
|
-
end
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
9
5
|
|
10
|
-
|
11
|
-
task :default => :test
|
6
|
+
task :default => :spec
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "pwinty3"
|
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(__FILE__)
|
data/bin/setup
ADDED
data/lib/pwinty.rb
CHANGED
@@ -1,88 +1,62 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
require "pwinty/base"
|
5
|
+
require "pwinty/country"
|
6
|
+
require "pwinty/http_errors"
|
7
|
+
require "pwinty/image"
|
8
|
+
require "pwinty/order"
|
9
|
+
require "pwinty/order_status"
|
10
|
+
require 'pwinty/photo_status'
|
11
|
+
require "pwinty/shipment"
|
12
|
+
require "pwinty/shipping_info"
|
1
13
|
require "pwinty/version"
|
2
|
-
require "multipart"
|
3
|
-
require "rest_client"
|
4
14
|
|
5
15
|
module Pwinty
|
16
|
+
class Error < StandardError; end
|
17
|
+
class AuthenticationError < Pwinty::Error; end
|
18
|
+
class OrderNotFound < Pwinty::Error; end
|
19
|
+
class StateIsInvalid < Pwinty::Error; end
|
6
20
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
21
|
+
MERCHANT_ID = ENV['PWINTY_MERCHANT_ID']
|
22
|
+
API_KEY = ENV['PWINTY_API_KEY']
|
23
|
+
BASE_URL = ENV['PWINTY_BASE_URL'] || 'https://sandbox.pwinty.com'
|
24
|
+
API_VERSION = 'v3.0'
|
11
25
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@pwinty = RestClient::Resource.new(domain, :headers => {
|
21
|
-
"X-Pwinty-MerchantId" => options[:merchant_id],
|
22
|
-
"X-Pwinty-REST-API-Key" => options[:api_key],
|
23
|
-
'Accept' => 'application/json'
|
24
|
-
})
|
25
|
-
end
|
26
|
-
|
27
|
-
def catalog(countryCode: 'US', qualityLevel: 'Standard')
|
28
|
-
JSON.parse @pwinty["/Catalogue/#{countryCode}/#{qualityLevel}"].get
|
29
|
-
end
|
30
|
-
|
31
|
-
# Orders
|
32
|
-
def get_orders
|
33
|
-
JSON.parse @pwinty["/Orders"].get
|
34
|
-
end
|
35
|
-
|
36
|
-
def create_order(**args)
|
37
|
-
JSON.parse @pwinty["/Orders"].post(args)
|
38
|
-
end
|
39
|
-
|
40
|
-
def update_order(**args)
|
41
|
-
JSON.parse @pwinty["/Orders/#{args[:id]}"].put(args)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Order Status
|
45
|
-
def get_order_status(id)
|
46
|
-
JSON.parse @pwinty["/Orders/#{id}/SubmissionStatus"].get
|
47
|
-
end
|
48
|
-
|
49
|
-
def update_order_status(id, status)
|
50
|
-
JSON.parse @pwinty["/Orders/#{id}/Status"].post(status: status)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Order Photos
|
54
|
-
def get_photos(orderId)
|
55
|
-
JSON.parse @pwinty["/Orders/#{orderId}/Photos"].get
|
26
|
+
class << self
|
27
|
+
attr_accessor :logger
|
28
|
+
def logger
|
29
|
+
@logger ||= Logger.new($stdout).tap do |log|
|
30
|
+
log.progname = self.name
|
31
|
+
end
|
32
|
+
end
|
56
33
|
end
|
57
34
|
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
def add_photo(**args)
|
64
|
-
headers = {}
|
65
|
-
orderId = args.delete(:orderId)
|
66
|
-
|
67
|
-
unless args[:file].nil?
|
68
|
-
args, headers = Multipart::Post.prepare_query(args)
|
69
|
-
end
|
70
|
-
|
71
|
-
JSON.parse @pwinty["/Orders/#{orderId}/Photos"].post(args, headers)
|
35
|
+
def self.url
|
36
|
+
"#{Pwinty::BASE_URL}/#{Pwinty::API_VERSION}/"
|
72
37
|
end
|
73
38
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
39
|
+
def self.headers
|
40
|
+
{
|
41
|
+
'X-Pwinty-MerchantId' => Pwinty::MERCHANT_ID,
|
42
|
+
'X-Pwinty-REST-API-Key' => Pwinty::API_KEY,
|
43
|
+
}
|
77
44
|
end
|
78
45
|
|
79
|
-
def
|
80
|
-
|
46
|
+
def self.conn
|
47
|
+
Faraday.new(url: url, headers: headers) do |config|
|
48
|
+
config.request :json
|
49
|
+
config.response :json
|
50
|
+
config.use Pwinty::HttpErrors
|
51
|
+
config.adapter Faraday.default_adapter
|
52
|
+
end
|
81
53
|
end
|
82
54
|
|
83
|
-
|
84
|
-
|
85
|
-
|
55
|
+
def self.collate_results(response_data, classType)
|
56
|
+
collection = []
|
57
|
+
response_data.each do |individual_attr|
|
58
|
+
collection << classType.new(individual_attr)
|
59
|
+
end
|
60
|
+
collection
|
86
61
|
end
|
87
|
-
end
|
88
62
|
end
|
data/lib/pwinty/base.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module Pwinty
|
2
|
+
class HttpErrors < Faraday::Response::Middleware
|
3
|
+
def on_complete(env)
|
4
|
+
msg = env[:body]
|
5
|
+
case env[:status]
|
6
|
+
when 401; raise Pwinty::AuthenticationError, msg
|
7
|
+
when 403; raise Pwinty::StateIsInvalid, msg
|
8
|
+
when 404; raise Pwinty::OrderNotFound, msg
|
9
|
+
when 500; raise Pwinty::Error, msg
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/pwinty/image.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Pwinty
|
2
|
+
|
3
|
+
class Image < Pwinty::Base
|
4
|
+
attribute :id, Types::Integer
|
5
|
+
attribute :url, Types::String
|
6
|
+
attribute :status, Types::String
|
7
|
+
attribute :copies, Types::Integer
|
8
|
+
attribute :sizing, Types::String
|
9
|
+
attribute :price, Types::Integer
|
10
|
+
attribute :priceToUser, Types::Integer.optional
|
11
|
+
attribute :md5Hash, Types::String.optional
|
12
|
+
attribute :previewUrl, Types::String.optional
|
13
|
+
attribute :thumbnailUrl, Types::String.optional
|
14
|
+
attribute :sku, Types::String
|
15
|
+
attribute :attributes, Types::Hash.schema(
|
16
|
+
substrateWeight: Types::String,
|
17
|
+
frame: Types::String,
|
18
|
+
edge: Types::String,
|
19
|
+
paperType: Types::String,
|
20
|
+
frameColour: Types::String,
|
21
|
+
).optional
|
22
|
+
attribute :errorMessage, Types::String.optional
|
23
|
+
end
|
24
|
+
end
|
data/lib/pwinty/order.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'dry/struct/with_setters'
|
2
|
+
|
3
|
+
require "pwinty/shipping_info"
|
4
|
+
|
5
|
+
module Pwinty
|
6
|
+
class Order < Pwinty::Base
|
7
|
+
include Dry::Struct::Setters
|
8
|
+
include Dry::Struct::Setters::MassAssignment
|
9
|
+
|
10
|
+
attribute :id, Types::Integer
|
11
|
+
attribute :address1, Types::String.optional
|
12
|
+
attribute :address2, Types::String.optional
|
13
|
+
attribute :postalOrZipCode, Types::String.optional
|
14
|
+
attribute :countryCode, Types::String
|
15
|
+
attribute :addressTownOrCity, Types::String.optional
|
16
|
+
attribute :recipientName, Types::String.optional
|
17
|
+
attribute :stateOrCounty, Types::String.optional
|
18
|
+
attribute :status, Types::String
|
19
|
+
attribute :payment, Types::String
|
20
|
+
attribute :paymentUrl, Types::String.optional
|
21
|
+
attribute :price, Types::Integer
|
22
|
+
attribute :shippingInfo, Pwinty::ShippingInfo
|
23
|
+
attribute :images, Types::Array.of(Pwinty::Image)
|
24
|
+
attribute :merchantOrderId, Types::String.optional
|
25
|
+
attribute :preferredShippingMethod, Types::String
|
26
|
+
attribute :mobileTelephone, Types::String.optional
|
27
|
+
attribute :created, Types::JSON::DateTime
|
28
|
+
attribute :lastUpdated, Types::JSON::DateTime
|
29
|
+
attribute :canCancel, Types::Bool
|
30
|
+
attribute :canHold, Types::Bool
|
31
|
+
attribute :canUpdateShipping, Types::Bool
|
32
|
+
attribute :canUpdateImages, Types::Bool
|
33
|
+
attribute :errorMessage, Types::String.optional
|
34
|
+
attribute :invoiceAmountNet, Types::Integer
|
35
|
+
attribute :invoiceTax, Types::Integer
|
36
|
+
attribute :invoiceCurrency, Types::String.optional
|
37
|
+
attribute :tag, Types::String.optional
|
38
|
+
|
39
|
+
def self.list
|
40
|
+
response = Pwinty.conn.get("orders?count=250&offset=0")
|
41
|
+
r_data = response.body['data']
|
42
|
+
# TODO There is some bug with offset in the API.
|
43
|
+
# total_count = r_data['count']
|
44
|
+
Pwinty.collate_results(r_data['content'], self)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def self.count
|
49
|
+
response = Pwinty.conn.get("orders?count=1&offset=0")
|
50
|
+
response.body['data']['count']
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def self.create(**args)
|
55
|
+
response = Pwinty.conn.post("orders", args)
|
56
|
+
new(response.body['data'])
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.find(id)
|
60
|
+
response = Pwinty.conn.get("orders/#{id}")
|
61
|
+
new(response.body['data'])
|
62
|
+
end
|
63
|
+
|
64
|
+
def update(**args)
|
65
|
+
update_body = self.to_hash.merge(args)
|
66
|
+
response = Pwinty.conn.put("orders/#{self.id}/", update_body)
|
67
|
+
self.assign_attributes(response.body['data'])
|
68
|
+
end
|
69
|
+
|
70
|
+
def submission_status
|
71
|
+
response = Pwinty.conn.get("orders/#{id}/SubmissionStatus")
|
72
|
+
Pwinty::OrderStatus.new(response.body['data'])
|
73
|
+
end
|
74
|
+
|
75
|
+
def submit
|
76
|
+
self.update_status 'Submitted'
|
77
|
+
end
|
78
|
+
|
79
|
+
def cancel
|
80
|
+
self.update_status 'Cancelled'
|
81
|
+
end
|
82
|
+
|
83
|
+
def hold
|
84
|
+
self.update_status 'AwaitingPayment'
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_image image
|
88
|
+
images = add_images([image])
|
89
|
+
self.images
|
90
|
+
end
|
91
|
+
|
92
|
+
def add_images images
|
93
|
+
response = Pwinty.conn.post("orders/#{self.id}/images/batch", images)
|
94
|
+
images = Pwinty.collate_results(response.body['data']['items'], Pwinty::Image)
|
95
|
+
self.images = self.images + images
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def update_status status
|
101
|
+
response = Pwinty.conn.post("orders/#{self.id}/status", {status: status})
|
102
|
+
success = response.status == 200
|
103
|
+
unless success
|
104
|
+
Pwinty.logger.warn response.body['statusTxt']
|
105
|
+
end
|
106
|
+
success
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'pwinty/photo_status'
|
2
|
+
|
3
|
+
module Pwinty
|
4
|
+
|
5
|
+
class OrderStatus < Pwinty::Base
|
6
|
+
attribute :id, Types::Coercible::Integer
|
7
|
+
attribute :isValid, Types::Bool
|
8
|
+
attribute :generalErrors, Types::Array.of(Types::String)
|
9
|
+
attribute :photos, Types::Array.of(Pwinty::PhotoStatus)
|
10
|
+
|
11
|
+
|
12
|
+
def self.check(id)
|
13
|
+
response = Pwinty.conn.get("orders/#{id}/SubmissionStatus")
|
14
|
+
new(response.body['data'])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Pwinty
|
2
|
+
|
3
|
+
class Shipment < Pwinty::Base
|
4
|
+
attribute :shipmentId, Types::String.optional
|
5
|
+
attribute :isTracked, Types::Bool
|
6
|
+
attribute :trackingNumber, Types::String.optional
|
7
|
+
attribute :trackingUrl, Types::String.optional
|
8
|
+
attribute :carrier, Types::String.optional
|
9
|
+
attribute :photoIds, Types::Array.of(Types::Integer)
|
10
|
+
attribute :earliestEstimatedArrivalDate, Types::JSON::DateTime
|
11
|
+
attribute :latestEstimatedArrivalDate, Types::JSON::DateTime
|
12
|
+
attribute :shippedOn, Types::JSON::DateTime.optional
|
13
|
+
end
|
14
|
+
end
|
data/lib/pwinty/version.rb
CHANGED
data/pwinty.gemspec
CHANGED
@@ -1,24 +1,39 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
4
|
require "pwinty/version"
|
4
5
|
|
5
|
-
Gem::Specification.new do |
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pwinty"
|
8
|
+
spec.version = Pwinty::VERSION
|
9
|
+
spec.authors = ["Thomas Harvey"]
|
10
|
+
spec.email = ["tom@alush.co.uk"]
|
11
|
+
|
12
|
+
spec.summary = %q{Order photo prints through Pwinty}
|
13
|
+
spec.description = "This wraps the Pwinty API at version 3 and aims to make your ruby life easier when interacting with the API."
|
14
|
+
spec.homepage = "https://github.com/tomharvey/pwinty3-rb"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
end
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
14
29
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
s.require_paths = ["lib"]
|
30
|
+
spec.add_development_dependency "vcr", "~> 5.0"
|
31
|
+
spec.add_development_dependency "webmock", "~> 3.6"
|
32
|
+
spec.add_development_dependency "simplecov", "~> 0.17"
|
19
33
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
34
|
+
spec.add_dependency "dry-struct", "~> 1.0"
|
35
|
+
spec.add_dependency "dry-struct-setters", "~> 0.2"
|
36
|
+
spec.add_dependency "faraday", "~> 0.15"
|
37
|
+
spec.add_dependency "faraday_middleware", "~> 0.13"
|
38
|
+
spec.add_dependency "json", "~> 2.2"
|
24
39
|
end
|