peddler 0.3.1 → 0.4.1
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.
- data/LICENSE +3 -3
- data/README.md +42 -105
- data/lib/peddler/feeds.rb +4 -184
- data/lib/peddler/fulfillment_inbound_shipment.rb +11 -0
- data/lib/peddler/fulfillment_inventory.rb +10 -0
- data/lib/peddler/fulfillment_outbound_shipment.rb +10 -0
- data/lib/peddler/orders.rb +10 -0
- data/lib/peddler/products.rb +11 -0
- data/lib/peddler/reports.rb +4 -94
- data/lib/peddler/sellers.rb +9 -0
- data/lib/peddler/service.rb +106 -0
- data/lib/peddler/version.rb +1 -1
- data/lib/peddler.rb +5 -17
- metadata +61 -175
- data/.gitignore +0 -5
- data/.rspec +0 -1
- data/.rvmrc +0 -2
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -47
- data/Rakefile +0 -12
- data/lib/peddler/client.rb +0 -229
- data/lib/peddler/handlers.rb +0 -38
- data/lib/peddler/inventory.rb +0 -140
- data/lib/peddler/legacy_reports.rb +0 -109
- data/lib/peddler/refunds.rb +0 -52
- data/lib/peddler/transport.rb +0 -135
- data/mussels.jpg +0 -0
- data/peddler.gemspec +0 -28
- data/spec/peddler/client_spec.rb +0 -45
- data/spec/peddler/feeds_spec.rb +0 -88
- data/spec/peddler/handlers_spec.rb +0 -12
- data/spec/peddler/inventory_spec.rb +0 -74
- data/spec/peddler/legacy_reports_spec.rb +0 -89
- data/spec/peddler/refunds_spec.rb +0 -42
- data/spec/peddler/reports_spec.rb +0 -26
- data/spec/peddler/transport_spec.rb +0 -65
- data/spec/spec_helper.rb +0 -7
- data/spec/support/amazon.yml.example +0 -2
- data/spec/support/amazon_credentials.rb +0 -3
- data/spec/support/vcr.rb +0 -13
- data/spec_rubies +0 -2
data/lib/peddler/inventory.rb
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
module Peddler
|
2
|
-
module Inventory
|
3
|
-
module Queue
|
4
|
-
# Returns number of inventory uploads queued at Amazon
|
5
|
-
def self.count(transport)
|
6
|
-
transport.legacize_request
|
7
|
-
transport.path << 'manual-reports/get-pending-uploads-count'
|
8
|
-
res = transport.execute_request
|
9
|
-
if res =~ /^<PendingUploadsCount>(.*)<\/PendingUploadsCount>$/
|
10
|
-
$1.to_i
|
11
|
-
else
|
12
|
-
nil
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# This is an inventory batch.
|
18
|
-
class Batch
|
19
|
-
attr_reader :id
|
20
|
-
attr_accessor :batch
|
21
|
-
|
22
|
-
def initialize(transport)
|
23
|
-
@transport = transport
|
24
|
-
@batch = []
|
25
|
-
end
|
26
|
-
|
27
|
-
# Uploads batch to Amazon.
|
28
|
-
def upload(params={})
|
29
|
-
raise PeddlerError.new('Batch already uploaded') unless @id.nil?
|
30
|
-
@transport.legacize_request
|
31
|
-
@transport.path << 'catalog-upload/'
|
32
|
-
|
33
|
-
case params[:method].to_s
|
34
|
-
when 'modify'
|
35
|
-
@transport.path << 'modify-only'
|
36
|
-
@transport.body = file_content(:short)
|
37
|
-
when 'purge'
|
38
|
-
@transport.path << 'purge-replace'
|
39
|
-
@transport.body = file_content
|
40
|
-
else
|
41
|
-
@transport.path << 'add-modify-delete'
|
42
|
-
@transport.body = file_content
|
43
|
-
end
|
44
|
-
params.delete(:method)
|
45
|
-
|
46
|
-
params = defaultize(params)
|
47
|
-
@transport.headers.merge!(params)
|
48
|
-
res = @transport.execute_request
|
49
|
-
|
50
|
-
if res =~ /^<BatchID>(.*)<\/BatchID>$/
|
51
|
-
@id = $1
|
52
|
-
else
|
53
|
-
@id = 0
|
54
|
-
end
|
55
|
-
true
|
56
|
-
end
|
57
|
-
|
58
|
-
# Returns upload file string.
|
59
|
-
def file_content(type=:long)
|
60
|
-
case type
|
61
|
-
when :long
|
62
|
-
out = "product-id\tproduct-id-type\titem-condition\tprice\tsku\tquantity\tadd-delete\twill-ship-internationally\texpedited-shipping\titem-note\titem-is-marketplace\tfulfillment-center-id\titem-name\titem-description\tcategory1\timage-url\tshipping-fee\tbrowse-path\tstorefront-feature\tboldface\tasin1\tasin2\tasin3\r\n"
|
63
|
-
@batch.each{ |item| out << item.to_s }
|
64
|
-
when :short
|
65
|
-
out = "sku\tprice\tquantity\r\n"
|
66
|
-
@batch.each{ |item| out << item.to_s(:short) }
|
67
|
-
end
|
68
|
-
out
|
69
|
-
end
|
70
|
-
|
71
|
-
# Adds an item to inventory.
|
72
|
-
def <<(item)
|
73
|
-
@batch << item
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def defaultize(params)
|
79
|
-
params = {
|
80
|
-
:upload_for => 'Marketplace',
|
81
|
-
:file_format => 'TabDelimited',
|
82
|
-
:asin_match_create => 'Y',
|
83
|
-
:asinate => 'Y',
|
84
|
-
:batch_id => 'Y',
|
85
|
-
:email => 'Y'
|
86
|
-
}.merge(params)
|
87
|
-
|
88
|
-
# Some Amazon dimwit figured he'd rather not camelize this one
|
89
|
-
if params[:enable_expedited_shipping]
|
90
|
-
params['enable-expedited-shipping'] = params[:enable_expedited_shipping]
|
91
|
-
params.delete(:enable_expedited_shipping)
|
92
|
-
else
|
93
|
-
params['enable-expedited-shipping'] = 'Y'
|
94
|
-
end
|
95
|
-
|
96
|
-
params
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
# This is an inventory item.
|
101
|
-
class Item
|
102
|
-
attr_accessor :product_id,
|
103
|
-
:product_id_type,
|
104
|
-
:item_condition,
|
105
|
-
:price,
|
106
|
-
:sku,
|
107
|
-
:quantity,
|
108
|
-
:add_delete,
|
109
|
-
:will_ship_internationally,
|
110
|
-
:expedited_shipping,
|
111
|
-
:item_note,
|
112
|
-
:item_is_marketplace,
|
113
|
-
:fulfillment_center_id,
|
114
|
-
:item_name,
|
115
|
-
:item_description,
|
116
|
-
:category1,
|
117
|
-
:image_url,
|
118
|
-
:shipping_fee,
|
119
|
-
:browse_path,
|
120
|
-
:storefront_feature,
|
121
|
-
:boldface,
|
122
|
-
:asin1,
|
123
|
-
:asin2,
|
124
|
-
:asin3
|
125
|
-
|
126
|
-
def initialize(params={})
|
127
|
-
params.each_pair{ |key, value| send("#{key.to_s}=", value) }
|
128
|
-
end
|
129
|
-
|
130
|
-
def to_s(type=:long)
|
131
|
-
case type
|
132
|
-
when :long
|
133
|
-
"#{self.product_id}\t#{self.product_id_type}\t#{self.item_condition}\t#{self.price}\t#{self.sku}\t#{self.quantity}\t#{self.add_delete}\t#{self.will_ship_internationally}\t#{self.expedited_shipping}\t#{self.item_note}\t#{self.item_is_marketplace}\t#{self.fulfillment_center_id}\t#{self.item_name}\t#{self.item_description}\t#{self.category1}\t#{self.image_url}\t#{self.shipping_fee}\t#{self.browse_path}\t#{self.storefront_feature}\t#{self.boldface}\t#{self.asin1}\t#{self.asin2}\t#{self.asin3}\r\n"
|
134
|
-
when :short
|
135
|
-
"#{self.sku}\t#{self.price}\t#{self.quantity}\r\n"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
module Peddler
|
2
|
-
|
3
|
-
# This module contains methods to manage legacy reports -- anything that comes before section 7 in the API docs.
|
4
|
-
module LegacyReports
|
5
|
-
|
6
|
-
# Returns statuses of most recent reports in an array of OpenStructs.
|
7
|
-
def self.latest(transport,name,params={})
|
8
|
-
transport.legacize_request
|
9
|
-
if name == :upload
|
10
|
-
transport.path << 'catalog-upload/get-batches'
|
11
|
-
transport.headers[:number_of_batches] = params[:count] if params[:count]
|
12
|
-
else
|
13
|
-
transport.path << 'manual-reports/get-report-status'
|
14
|
-
transport.headers[:report_name] = name.to_s.camelize
|
15
|
-
transport.headers[:number_of_reports] = params[:count] if params[:count]
|
16
|
-
end
|
17
|
-
res = transport.execute_request
|
18
|
-
Peddler::Handlers::XMLHandler.parse_legacy(Hash.from_xml(res)) || []
|
19
|
-
end
|
20
|
-
|
21
|
-
# Requests a report to be generated and returns the report instance if request is successful.
|
22
|
-
def self.generate(transport,name,params={})
|
23
|
-
transport.legacize_request
|
24
|
-
transport.path << 'manual-reports/generate-report-now'
|
25
|
-
transport.headers[:report_name] = name.to_s.camelize
|
26
|
-
transport.headers.merge!(params)
|
27
|
-
res = transport.execute_request
|
28
|
-
res =~ /SUCCESS/ ? Peddler::LegacyReports::Report.new(transport, name) : false
|
29
|
-
end
|
30
|
-
|
31
|
-
# A legacy report
|
32
|
-
class Report
|
33
|
-
attr_accessor :name, :id, :product_line, :frequency
|
34
|
-
|
35
|
-
def initialize(transport, name=nil, params={})
|
36
|
-
@transport, @name = transport, name
|
37
|
-
params.each_pair{ |key, value| self.send "#{key}=", value }
|
38
|
-
end
|
39
|
-
|
40
|
-
def body
|
41
|
-
return nil if @name == :upload && @id.nil?
|
42
|
-
@body ||= download
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def download
|
48
|
-
return false if @name.nil? && @id.nil?
|
49
|
-
case @name.to_s
|
50
|
-
when 'upload'
|
51
|
-
@transport.legacize_request
|
52
|
-
@transport.path << 'download/errorlog'
|
53
|
-
@transport.headers['BatchID'] = @id
|
54
|
-
@transport.execute_request
|
55
|
-
else
|
56
|
-
@transport.legacize_request
|
57
|
-
@transport.path << 'download/report'
|
58
|
-
if @id.nil?
|
59
|
-
@transport.headers[:report_name] = @name.to_s.camelize
|
60
|
-
if @name == :preorder
|
61
|
-
@transport.headers['productline'] = @product_line if @product_line
|
62
|
-
@transport.headers['frequency'] = @frequency if @frequency
|
63
|
-
end
|
64
|
-
else
|
65
|
-
@transport.headers['ReportID'] = @id
|
66
|
-
end
|
67
|
-
@transport.execute_request
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
class Status < OpenStruct
|
73
|
-
def initialize(input)
|
74
|
-
if input.kind_of? String
|
75
|
-
hash = input.scan(/([a-z]+)=([^=]+)($| )/).inject({}){ |memo, value| memo.merge( { @keymap[value[0]] => value[1].strip }) }
|
76
|
-
end
|
77
|
-
super(hash)
|
78
|
-
end
|
79
|
-
|
80
|
-
def id
|
81
|
-
@table[:id] || self.object_id
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
class ReportStatus < Status
|
86
|
-
def initialize(input)
|
87
|
-
@keymap = {
|
88
|
-
'reportstarttime' => 'starts_at',
|
89
|
-
'reportendtime' => 'ends_at',
|
90
|
-
'reportid' => 'id' }
|
91
|
-
super(input)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
class UploadStatus < Status
|
96
|
-
def initialize(input)
|
97
|
-
@keymap = {
|
98
|
-
'status' => 'status',
|
99
|
-
'batchid' => 'id',
|
100
|
-
'numberofwarnings' => 'number_of_warnings',
|
101
|
-
'activateditems' => 'activated_items',
|
102
|
-
'itemsnotacivated' => 'items_not_activated',
|
103
|
-
'itemsnotactivated' => 'items_not_activated',
|
104
|
-
'dateandtime' => 'datetime' }
|
105
|
-
super(input)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
data/lib/peddler/refunds.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
module Peddler
|
2
|
-
module Refunds
|
3
|
-
# This is a refund batch.
|
4
|
-
class Batch
|
5
|
-
attr_accessor :batch
|
6
|
-
|
7
|
-
def initialize(transport)
|
8
|
-
@transport = transport
|
9
|
-
@batch = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def file_content
|
13
|
-
out = "order-id\tpayments-transaction-id\trefund-amount\treason\tmessage\r\n"
|
14
|
-
@file_content = @batch.inject(out){ |memo, item| memo << item.to_s }
|
15
|
-
end
|
16
|
-
|
17
|
-
def <<(item)
|
18
|
-
@batch << item
|
19
|
-
end
|
20
|
-
|
21
|
-
def upload
|
22
|
-
raise PeddlerError.new("Batch already uploaded") if @completed
|
23
|
-
@transport.legacize_request
|
24
|
-
@transport.path << "catalog-upload/batch-refund"
|
25
|
-
@transport.body = file_content
|
26
|
-
res = @transport.execute_request
|
27
|
-
@completed = true if res == "<Success>SUCCESS</Success>"
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
# This is a refund.
|
33
|
-
class Item
|
34
|
-
REFUND_REASONS = %w{ GeneralAdjustment CouldNotShip DifferentItem MerchandiseNotReceived MerchandiseNotAsDescribed }
|
35
|
-
|
36
|
-
attr_accessor :order_id, :payments_transaction_id, :refund_amount, :message
|
37
|
-
attr_reader :reason
|
38
|
-
|
39
|
-
def initialize(options={})
|
40
|
-
options.each_pair{ |key, value| send("#{key.to_s}=", value) }
|
41
|
-
end
|
42
|
-
|
43
|
-
def reason=(reason)
|
44
|
-
@reason = reason if REFUND_REASONS.include?(reason)
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_s
|
48
|
-
"#{self.order_id}\t#{self.payments_transaction_id}\t#{self.refund_amount}\t#{self.reason}\t#{self.message}\r\n"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/peddler/transport.rb
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
module Peddler
|
2
|
-
class PeddlerError < StandardError
|
3
|
-
def initialize(msg)
|
4
|
-
super(msg)
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
# Our work horse. Runs on top of Net::HTTP.
|
9
|
-
class Transport
|
10
|
-
API_HOSTS = {
|
11
|
-
:us => 'secure.amazon.com',
|
12
|
-
:uk => 'secure.amazon.co.uk',
|
13
|
-
:de => 'secure.amazon.de',
|
14
|
-
:ca => 'secure.amazon.ca',
|
15
|
-
:fr => 'secure.amazon.fr',
|
16
|
-
:jp => 'vendornet.amazon.co.jp'
|
17
|
-
}
|
18
|
-
|
19
|
-
BASE_HEADERS = {
|
20
|
-
'User-Agent' => "Peddler/#{Peddler::VERSION}",
|
21
|
-
'Content-Type' => 'text/xml;charset=utf-8',
|
22
|
-
'Cookie' => 'x-main=YvjPkwfntqDKun0QEmVRPcTTZDMe?Tn?; ubid-main=002-8989859-9917520; ubid-tacbus=019-5423258-4241018;x-tacbus=vtm4d53DvX@Sc9LxTnAnxsFL3DorwxJa; ubid-tcmacb=087-8055947-0795529; ubid-ty2kacbus=161-5477122-2773524; session-id=087-178254-5924832;session-id-time=950660664'
|
23
|
-
}
|
24
|
-
|
25
|
-
BASE_PARAMS = {
|
26
|
-
'Service' => 'MerchantQueryService'
|
27
|
-
}
|
28
|
-
|
29
|
-
attr_writer :username, :password
|
30
|
-
attr_accessor :path, :query_params, :headers, :body
|
31
|
-
|
32
|
-
#Returns request instance
|
33
|
-
def request
|
34
|
-
req = request_method.new("#{path.gsub(/\/$/, "")}/#{query_string}")
|
35
|
-
headers.each do |header, value|
|
36
|
-
if header.kind_of? Symbol
|
37
|
-
req[header.to_s.gsub(/_/, '')] = value
|
38
|
-
else
|
39
|
-
req[header] = value
|
40
|
-
end
|
41
|
-
end
|
42
|
-
req.basic_auth(@username, @password) if @username && @password
|
43
|
-
req.body = body if body
|
44
|
-
req
|
45
|
-
end
|
46
|
-
|
47
|
-
def execute_request
|
48
|
-
begin
|
49
|
-
conn.start do |http|
|
50
|
-
res = http.request(request)
|
51
|
-
case res
|
52
|
-
when Net::HTTPSuccess
|
53
|
-
res.body
|
54
|
-
else
|
55
|
-
raise PeddlerError.new(res.body)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def clear_request
|
62
|
-
self.headers = BASE_HEADERS.dup
|
63
|
-
self.body = nil
|
64
|
-
end
|
65
|
-
|
66
|
-
def legacize_request
|
67
|
-
clear_request
|
68
|
-
self.path = '/exec/panama/seller-admin/'
|
69
|
-
self.query_params = {}
|
70
|
-
end
|
71
|
-
|
72
|
-
def modernize_request
|
73
|
-
clear_request
|
74
|
-
self.path = '/query/'
|
75
|
-
self.query_params = BASE_PARAMS.dup
|
76
|
-
end
|
77
|
-
|
78
|
-
def region=(region)
|
79
|
-
@conn = nil
|
80
|
-
region = region.to_sym
|
81
|
-
if API_HOSTS.has_key?(region)
|
82
|
-
@region = region
|
83
|
-
else
|
84
|
-
raise PeddlerError.new('Region not recognized')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def url
|
89
|
-
URI.parse("https://#{host}#{path}#{query_string}")
|
90
|
-
end
|
91
|
-
|
92
|
-
def dump_headers(msg)
|
93
|
-
msg.each_header do |k, v|
|
94
|
-
p "#{k}=#{v}"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
#Returns the Net::HTTP instance.
|
101
|
-
def conn
|
102
|
-
if @conn
|
103
|
-
@conn
|
104
|
-
else
|
105
|
-
conn = Net::HTTP.new(host, 443)
|
106
|
-
conn.use_ssl = true
|
107
|
-
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
108
|
-
@conn = conn
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def request_method
|
113
|
-
if !body.nil? || (query_params && !query_params.empty?)
|
114
|
-
Net::HTTP::Post
|
115
|
-
else
|
116
|
-
Net::HTTP::Get
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def host
|
121
|
-
API_HOSTS[@region]
|
122
|
-
end
|
123
|
-
|
124
|
-
def query_string
|
125
|
-
if query_params && !query_params.empty?
|
126
|
-
params = query_params.collect do |k, v|
|
127
|
-
k = k.to_s.gsub(/_([a-z])/) { $1.upcase } if k.kind_of? Symbol
|
128
|
-
v = v.httpdate if v.respond_to? :httpdate
|
129
|
-
"#{k}=#{v}"
|
130
|
-
end
|
131
|
-
"?#{params.join('&')}"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
data/mussels.jpg
DELETED
Binary file
|
data/peddler.gemspec
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path('../lib', __FILE__)
|
3
|
-
require 'peddler/version'
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
s.name = 'peddler'
|
7
|
-
s.version = Peddler::VERSION
|
8
|
-
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ['Hakan Ensari']
|
10
|
-
s.email = ['hakan.ensari@papercavalier.com']
|
11
|
-
s.homepage = 'http://github.com/papercavalier/peddler'
|
12
|
-
s.summary = %q{A Ruby wrapper to the Amazon Inventory Management API}
|
13
|
-
s.description = %q{Peddler is a Ruby wrapper to the Amazon Inventory Management API.}
|
14
|
-
|
15
|
-
s.rubyforge_project = 'peddler'
|
16
|
-
|
17
|
-
s.files = `git ls-files`.split("\n")
|
18
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
-
s.require_paths = ['lib']
|
21
|
-
|
22
|
-
s.add_dependency 'activesupport', '>= 2.3.2'
|
23
|
-
s.add_development_dependency 'rdiscount', '~> 1.6.5'
|
24
|
-
s.add_development_dependency 'sdoc-helpers', '~> 0.1.4'
|
25
|
-
s.add_development_dependency 'rspec', '~> 2.0.0'
|
26
|
-
s.add_development_dependency 'vcr', '~> 1.2.0'
|
27
|
-
s.add_development_dependency 'webmock', '~> 1.4.0'
|
28
|
-
end
|
data/spec/peddler/client_spec.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Peddler
|
4
|
-
describe Client do
|
5
|
-
let(:client) do
|
6
|
-
Peddler::Client.new(
|
7
|
-
:username => 'seller@example.com',
|
8
|
-
:password => 'secret',
|
9
|
-
:region => 'us'
|
10
|
-
)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "returns a new inventory batch" do
|
14
|
-
client.new_inventory_batch.should be_an_instance_of Peddler::Inventory::Batch
|
15
|
-
end
|
16
|
-
|
17
|
-
it "returns a new inventory item" do
|
18
|
-
client.new_inventory_item.should be_an_instance_of Peddler::Inventory::Item
|
19
|
-
end
|
20
|
-
|
21
|
-
it "returns a new order fulfillment feed" do
|
22
|
-
client.new_order_fulfillment_feed.should be_an_instance_of Peddler::Feeds::OrderFulfillment::Batch
|
23
|
-
end
|
24
|
-
|
25
|
-
it "returns a new fulfilled order" do
|
26
|
-
client.new_fulfilled_order.should be_an_instance_of Peddler::Feeds::OrderFulfillment::Item
|
27
|
-
end
|
28
|
-
|
29
|
-
it "returns a new order cancellation feed" do
|
30
|
-
client.new_order_cancellation_feed.should be_an_instance_of Peddler::Feeds::OrderCancellation::Batch
|
31
|
-
end
|
32
|
-
|
33
|
-
it "returns a new cancelled order" do
|
34
|
-
client.new_cancelled_order.should be_an_instance_of Peddler::Feeds::OrderCancellation::Item
|
35
|
-
end
|
36
|
-
|
37
|
-
it "returns a new refund batch" do
|
38
|
-
client.new_refund_batch.should be_an_instance_of Peddler::Refunds::Batch
|
39
|
-
end
|
40
|
-
|
41
|
-
it "returns a new report" do
|
42
|
-
client.new_report(:foo).should be_an_instance_of Peddler::LegacyReports::Report
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/spec/peddler/feeds_spec.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Peddler
|
4
|
-
module Feeds
|
5
|
-
module OrderFulfillment
|
6
|
-
describe Batch do
|
7
|
-
let(:transport) do
|
8
|
-
transport = Peddler::Transport.new
|
9
|
-
transport.modernize_request
|
10
|
-
transport
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:feed) { Peddler::Feeds::OrderFulfillment::Batch.new(transport) }
|
14
|
-
|
15
|
-
let(:fulfilled_order) do
|
16
|
-
Peddler::Feeds::OrderFulfillment::Item.new(
|
17
|
-
:order_id => '123-1234567-1234567',
|
18
|
-
:ship_date => Date.parse('2009-08-11').to_s
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'adds items to batch' do
|
23
|
-
feed.batch.size.should == 0
|
24
|
-
feed << fulfilled_order
|
25
|
-
feed.batch.size.should == 1
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'creates content for upload' do
|
29
|
-
feed << fulfilled_order
|
30
|
-
feed.file_content.should == "order-id\torder-item-id\tquantity\tship-date\tcarrier-code\tcarrier-name\ttracking-number\tship-method\r\n123-1234567-1234567\t\t\t2009-08-11\t\t\t\t\r\n"
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'uploads' do
|
34
|
-
feed.id.should == nil
|
35
|
-
transport.stub!(:execute_request).and_return('<?xml version="1.0" encoding="UTF-8"?><Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://merchant-query.amazon.com/query/schema/MerchantQueryResponses.xsd"><Upload> <UploadId>130895733</UploadId><UploadType>_POST_FLAT_FILE_FULFILLMENT_DATA_</UploadType><UploadStatus>_SUBMITTED_</UploadStatus><SubmittedDate>2007-04-05T00:34:00+0000</SubmittedDate></Upload></Response>')
|
36
|
-
feed.upload
|
37
|
-
feed.id.should == '130895733'
|
38
|
-
feed.status.should == '_SUBMITTED_'
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'refreshes status' do
|
42
|
-
transport.stub!(:execute_request).and_return('<?xml version="1.0" encoding="UTF-8"?><Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://merchant-query.amazon.com/query/schema/MerchantQueryResponses.xsd"><Upload> <UploadId>130895733</UploadId><UploadType>_POST_FLAT_FILE_FULFILLMENT_DATA_</UploadType><UploadStatus>_SUBMITTED_</UploadStatus><SubmittedDate>2007-04-05T00:34:00+0000</SubmittedDate></Upload></Response>')
|
43
|
-
feed.upload
|
44
|
-
transport.stub!(:execute_request).and_return('<?xml version="1.0" encoding="UTF-8"?><Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://merchant-query.amazon.com/query/schema/MerchantQueryResponses.xsd"><UploadsStatusList><Upload><UploadId>130895733</UploadId><UploadType>_POST_FLAT_FILE_FULFILLMENT_DATA_</UploadType><UploadStatus>_IN_PROGRESS_</UploadStatus><SubmittedDate>2007-04-05T00:34:00+0000</SubmittedDate><StartedProcessingDate>2007-04-05T00:39:00+0000</StartedProcessingDate></Upload></UploadsStatusList></Response>')
|
45
|
-
feed.status.should == '_SUBMITTED_'
|
46
|
-
feed.status!.should == '_IN_PROGRESS_'
|
47
|
-
transport.stub!(:execute_request).and_return('<?xml version="1.0" encoding="UTF-8"?><Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://merchant-query.amazon.com/query/schema/MerchantQueryResponses.xsd"><UploadsStatusList><Upload><UploadId>130895733</UploadId><UploadType>_POST_FLAT_FILE_FULFILLMENT_DATA_</UploadType><UploadStatus>_DONE_</UploadStatus><SubmittedDate>2007-04-05T00:34:00+0000</SubmittedDate><StartedProcessingDate>2007-04-05T00:39:00+0000</StartedProcessingDate><CompletedProcessingDate>2007-04-05T01:02:00+0000</CompletedProcessingDate><MessagesProcessed>2</MessagesProcessed><MessagesSuccessful>2</MessagesSuccessful><MessagesWithErrors>0</MessagesWithErrors><MessagesWithWarnings>0</MessagesWithWarnings><RelatedDownloadsList><Download><DownloadId>3404021</DownloadId><DownloadType>FeedSummaryReport</DownloadType><RelatedReferenceId>4307285844</RelatedReferenceId><AvailableDate>2009-04-24T23:47:24+00:00</AvailableDate><Acknowledged>FALSE</Acknowledged></Download></RelatedDownloadsList></Upload></UploadsStatusList></Response>')
|
48
|
-
feed.status!.should == '_DONE_'
|
49
|
-
feed.download.id.should == '3404021'
|
50
|
-
feed.download.available_at.should == '2009-04-24T23:47:24+00:00'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
module OrderCancellation
|
56
|
-
describe Batch do
|
57
|
-
let(:transport) do
|
58
|
-
transport = Peddler::Transport.new
|
59
|
-
transport.modernize_request
|
60
|
-
transport
|
61
|
-
end
|
62
|
-
let(:feed) { Peddler::Feeds::OrderCancellation::Batch.new(transport) }
|
63
|
-
let(:cancelled_order) { Peddler::Feeds::OrderCancellation::Item.new(:order_id => '123-1234567-1234567') }
|
64
|
-
|
65
|
-
it 'adds items to batch' do
|
66
|
-
feed.batch.size.should == 0
|
67
|
-
feed << cancelled_order
|
68
|
-
feed.batch.size.should == 1
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'creates content for upload' do
|
72
|
-
feed << cancelled_order
|
73
|
-
feed.file_content.should == "TemplateType=OrderCancellation Version=1.0/1.0.3 This row for Amazon.com use only. Do not modify or delete.\r\norder-id\tcancellation-reason-code\tamazon-order-item-code\r\n123-1234567-1234567\t\t\r\n"
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'raises error if cancellation reason code is given but Amazon order item code is missing' do
|
77
|
-
cancelled_order.cancellation_reason_code = 'BuyerCanceled'
|
78
|
-
lambda { cancelled_order.to_s }.should raise_error(PeddlerError)
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'raises error if Amazon order item code is given but cancellation reason code is missing' do
|
82
|
-
cancelled_order.amazon_order_item_code = '111111111111'
|
83
|
-
lambda { cancelled_order.to_s }.should raise_error(PeddlerError)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Peddler
|
4
|
-
module Handlers
|
5
|
-
describe TabDelimitedHandler do
|
6
|
-
it "parses tab-delimited text" do
|
7
|
-
text = Peddler::Handlers::TabDelimitedHandler.decode_response("title\tautor\nA Thousand Plateaus\tGilles Deleuze\n")
|
8
|
-
text[0].title.should == 'A Thousand Plateaus'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Peddler
|
4
|
-
module Inventory
|
5
|
-
describe Queue do
|
6
|
-
it 'shows queue count' do
|
7
|
-
transport = Peddler::Transport.new
|
8
|
-
transport.legacize_request
|
9
|
-
transport.stub!(:execute_request).and_return('<PendingUploadsCount>1</PendingUploadsCount>')
|
10
|
-
Peddler::Inventory::Queue.count(transport).should == 1
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe Batch do
|
15
|
-
let(:transport) do
|
16
|
-
transport = Peddler::Transport.new
|
17
|
-
transport.legacize_request
|
18
|
-
transport
|
19
|
-
end
|
20
|
-
|
21
|
-
let(:inventory) { Peddler::Inventory::Batch.new(transport) }
|
22
|
-
let(:item) do
|
23
|
-
Peddler::Inventory::Item.new(
|
24
|
-
:product_id => '1234567890',
|
25
|
-
:price => 100.00,
|
26
|
-
:sku => 'FOO-SKU',
|
27
|
-
:quantity => 10
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'adds items to batch' do
|
32
|
-
inventory.batch.size.should == 0
|
33
|
-
inventory << item
|
34
|
-
inventory.batch.size.should == 1
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'generates an upload file' do
|
38
|
-
inventory << item
|
39
|
-
inventory.file_content.should == "product-id\tproduct-id-type\titem-condition\tprice\tsku\tquantity\tadd-delete\twill-ship-internationally\texpedited-shipping\titem-note\titem-is-marketplace\tfulfillment-center-id\titem-name\titem-description\tcategory1\timage-url\tshipping-fee\tbrowse-path\tstorefront-feature\tboldface\tasin1\tasin2\tasin3\r\n1234567890\t\t\t100.0\tFOO-SKU\t10\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n"
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'generates a modify-only upload file' do
|
43
|
-
inventory << item
|
44
|
-
inventory.file_content(:short).should == "sku\tprice\tquantity\r\nFOO-SKU\t100.0\t10\r\n"
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'generates default headers for uploading' do
|
48
|
-
params = inventory.send(:defaultize,
|
49
|
-
:file_format => 'UIEE',
|
50
|
-
:enable_expedited_shipping => 'N'
|
51
|
-
)
|
52
|
-
params[:method].should be_nil
|
53
|
-
params[:upload_for].should == 'Marketplace'
|
54
|
-
params[:email].should == 'Y'
|
55
|
-
params[:file_format].should == 'UIEE'
|
56
|
-
params['enable-expedited-shipping'].should == 'N'
|
57
|
-
params[:enable_expedited_shipping].should be_nil
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'uploads batch' do
|
61
|
-
transport.stub!(:execute_request).and_return('<BatchID>2585199250</BatchID>')
|
62
|
-
inventory.upload.should == true
|
63
|
-
inventory.id.should == '2585199250'
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'raises error if a subsequent upload is attempted' do
|
67
|
-
transport.stub!(:execute_request).and_return('<BatchID>2585199250</BatchID>')
|
68
|
-
inventory.upload.should == true
|
69
|
-
inventory.id.should_not == nil
|
70
|
-
lambda { inventory.upload }.should raise_error(PeddlerError)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|