peddler 0.1.3 → 0.2.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.
- data/History.txt +4 -1
- data/README.rdoc +1 -1
- data/Rakefile +12 -12
- data/VERSION.yml +2 -2
- data/lib/peddler/client.rb +39 -17
- data/lib/peddler/feeds.rb +49 -46
- data/lib/peddler/handlers.rb +8 -32
- data/lib/peddler/inventory.rb +67 -35
- data/lib/peddler/legacy_reports.rb +3 -2
- data/lib/peddler/reports.rb +31 -28
- data/lib/peddler.rb +14 -20
- data/peddler.gemspec +9 -9
- data/spec/peddler/feeds_spec.rb +25 -25
- data/spec/peddler/handlers_spec.rb +3 -10
- data/spec/peddler/inventory_spec.rb +22 -20
- data/spec/peddler/legacy_reports_spec.rb +29 -29
- metadata +6 -6
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -115,4 +115,4 @@ Great sales. For a change, let's download something different from Amazon. Here'
|
|
115
115
|
|
116
116
|
Run rdoc and check the source for more detailed info.
|
117
117
|
|
118
|
-
Copyright © 2009 Hakan
|
118
|
+
Copyright © 2009 Hakan Şenol Ensari, released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
3
|
begin
|
4
|
-
require
|
4
|
+
require 'jeweler'
|
5
5
|
Jeweler::Tasks.new do |s|
|
6
|
-
s.name =
|
7
|
-
s.summary =
|
8
|
-
s.email =
|
9
|
-
s.homepage =
|
10
|
-
s.description =
|
11
|
-
s.authors = [
|
12
|
-
s.add_dependency
|
13
|
-
s.add_development_dependency
|
6
|
+
s.name = 'peddler'
|
7
|
+
s.summary = 'A Ruby wrapper to the Amazon Inventory Management API'
|
8
|
+
s.email = 'hakan.ensari@papercavalier.com'
|
9
|
+
s.homepage = 'http://snl.github.com/peddler'
|
10
|
+
s.description = 'Peddler is a Ruby wrapper to the Amazon Inventory Management API.'
|
11
|
+
s.authors = ['Hakan Şenol Ensari']
|
12
|
+
s.add_dependency 'activesupport', '>= 2.3.5'
|
13
|
+
s.add_development_dependency 'rspec', '>= 1.2.9'
|
14
14
|
end
|
15
15
|
Jeweler::GemcutterTasks.new
|
16
16
|
rescue LoadError
|
17
|
-
puts
|
17
|
+
puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
|
18
18
|
end
|
data/VERSION.yml
CHANGED
data/lib/peddler/client.rb
CHANGED
@@ -1,33 +1,38 @@
|
|
1
1
|
# = Peddler
|
2
|
-
# Peddler is a Ruby wrapper to the Amazon Inventory management API.
|
2
|
+
# Peddler is a Ruby wrapper to the {Amazon Inventory management API}[https://images-na.ssl-images-amazon.com/images/G/01/Amazon_AIM/Amazon_AIM.pdf].
|
3
3
|
#
|
4
|
-
# Peddler::Client
|
4
|
+
# Peddler::Client contains some detailed explanation and examples of usage.
|
5
5
|
module Peddler
|
6
6
|
# This is the public interface of the Peddler library.
|
7
7
|
class Client
|
8
8
|
# Creates a client instance.
|
9
9
|
#
|
10
|
-
# client = Peddler::Client.new
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# client = Peddler::Client.new(
|
11
|
+
# :username => 'foo@bar.com',
|
12
|
+
# :password => 'secret',
|
13
|
+
# :region => 'us'
|
14
|
+
# )
|
13
15
|
#
|
14
16
|
def initialize(params={})
|
15
|
-
params.each_pair { |key, value| self.send("#{key}=", value) }
|
17
|
+
params.each_pair { |key, value| self.send("#{key}=", value.to_s) }
|
16
18
|
end
|
17
19
|
|
20
|
+
# Sets username.
|
18
21
|
def username=(username)
|
19
22
|
self.transport.username = username
|
20
23
|
end
|
21
24
|
|
25
|
+
# Sets password.
|
22
26
|
def password=(password)
|
23
27
|
self.transport.password = password
|
24
28
|
end
|
25
29
|
|
26
30
|
# Sets Amazon region.
|
27
31
|
#
|
28
|
-
#
|
32
|
+
# client.region = :jp
|
33
|
+
#
|
29
34
|
def region=(region)
|
30
|
-
self.transport.region = region
|
35
|
+
self.transport.region = region.to_s
|
31
36
|
end
|
32
37
|
|
33
38
|
# Creates an inventory batch.
|
@@ -40,6 +45,9 @@ module Peddler
|
|
40
45
|
# :quantity => 1)
|
41
46
|
# batch << book
|
42
47
|
# batch.upload
|
48
|
+
#
|
49
|
+
# Once the batch is processed, you may view the report:
|
50
|
+
#
|
43
51
|
# report = client.new_report :upload, :id => batch.id
|
44
52
|
# p report.body
|
45
53
|
# => "Feed Processing Summary:\n\tNumber of records processed\t\t1\n\tNumber of records successful\t\t1\n\n"
|
@@ -48,8 +56,18 @@ module Peddler
|
|
48
56
|
Peddler::Inventory::Batch.new(self.transport.dup)
|
49
57
|
end
|
50
58
|
|
59
|
+
# A short-hand method to purge inventory.
|
60
|
+
#
|
61
|
+
# client.purge_inventory
|
62
|
+
#
|
63
|
+
def purge_inventory
|
64
|
+
empty_batch = Peddler::Inventory::Batch.new(self.transport.dup)
|
65
|
+
empty_batch.upload(:method => 'purge')
|
66
|
+
|
67
|
+
end
|
68
|
+
|
51
69
|
# Creates an inventory item. Parameter keys are lowercased and underscored but otherwise the same as
|
52
|
-
#
|
70
|
+
# the colum titles in the tab-delimited upload templates provided by Amazon.
|
53
71
|
def new_inventory_item(params={})
|
54
72
|
Peddler::Inventory::Item.new(params)
|
55
73
|
end
|
@@ -140,13 +158,17 @@ module Peddler
|
|
140
158
|
Peddler::Refunds::Item.new(params)
|
141
159
|
end
|
142
160
|
|
143
|
-
# Creates an instance for an already-generated report. Works only with
|
144
|
-
# anything that comes before section 7 in the API
|
161
|
+
# Creates an instance for an already-generated report. Works only with
|
162
|
+
# legacy reports, meaning anything that comes before section 7 in the API
|
163
|
+
# docs.
|
145
164
|
#
|
146
|
-
# Possible report names: [:upload, :order, :preorder, :batch_refund,
|
165
|
+
# Possible report names: [:upload, :order, :preorder, :batch_refund,
|
166
|
+
# :open_listings, :open_listings_lite, :open_listings_liter]
|
147
167
|
#
|
148
|
-
# You can download a specific report by using its ID. Otherwise, the
|
149
|
-
#
|
168
|
+
# You can download a specific report by using its ID. Otherwise, the
|
169
|
+
# instance will fetch the latest available report. One oddball exception:
|
170
|
+
# Upload reports do require an ID and will return nil if you don't provide
|
171
|
+
# one.
|
150
172
|
#
|
151
173
|
# orders_report = client.new_report :order
|
152
174
|
# orders = client.detab(orders_report.body)
|
@@ -171,8 +193,7 @@ module Peddler
|
|
171
193
|
#
|
172
194
|
# client.generate_report :order, :number_of_days => 15
|
173
195
|
#
|
174
|
-
# A word of caution. Open listings may crap up with larger inventories.
|
175
|
-
# HTTP client to get that working again.
|
196
|
+
# A word of caution. Open listings may crap up with larger inventories.
|
176
197
|
def generate_report(name,params={})
|
177
198
|
Peddler::LegacyReports.generate(self.transport, name, params)
|
178
199
|
end
|
@@ -207,7 +228,8 @@ module Peddler
|
|
207
228
|
Peddler::Handlers::TabDelimitedHandler.decode_response(msg)
|
208
229
|
end
|
209
230
|
|
210
|
-
|
231
|
+
private
|
232
|
+
|
211
233
|
def transport #:nodoc:all
|
212
234
|
@transport ||= Peddler::Transport.new
|
213
235
|
end
|
data/lib/peddler/feeds.rb
CHANGED
@@ -1,34 +1,38 @@
|
|
1
1
|
module Peddler
|
2
|
-
|
3
|
-
#
|
2
|
+
|
3
|
+
# This module includes functionality to handle the charge-when-ship-related
|
4
|
+
# feeds Amazon added to the API in 2009.
|
4
5
|
module Feeds
|
5
|
-
|
6
|
-
#
|
6
|
+
|
7
|
+
# This is a downloadable file. Outputs Amazon's response verbatim for now.
|
7
8
|
class Download
|
8
9
|
attr_accessor :id, :type, :related_reference_id, :available_at, :acknowledged
|
9
10
|
|
11
|
+
MAPPED_PARAMS = {
|
12
|
+
'DownloadId' => 'id',
|
13
|
+
'DownloadType' => 'type',
|
14
|
+
'RelatedReferenceId' => 'related_reference_id',
|
15
|
+
'AvailableDate' => 'available_at',
|
16
|
+
'Acknowledged' => 'acknowledged'}
|
17
|
+
|
10
18
|
def initialize(transport, params={})
|
11
|
-
@mapped_params = {
|
12
|
-
"DownloadId" => "id",
|
13
|
-
"DownloadType" => "type",
|
14
|
-
"RelatedReferenceId" => "related_reference_id",
|
15
|
-
"AvailableDate" => "available_at",
|
16
|
-
"Acknowledged" => "acknowledged"}
|
17
19
|
@transport = transport
|
18
|
-
params.each_pair{ |
|
20
|
+
params.each_pair{ |k, v| self.send "#{MAPPED_PARAMS[k]}=", v }
|
19
21
|
end
|
20
22
|
|
21
|
-
# Retrieves and returns report
|
23
|
+
# Retrieves and returns report.
|
22
24
|
def to_s
|
23
25
|
@body ||= download_report
|
24
26
|
end
|
25
|
-
|
27
|
+
|
28
|
+
private
|
29
|
+
|
26
30
|
def download_report
|
27
31
|
return nil if @id.nil?
|
28
32
|
@transport.modernize_request
|
29
33
|
@transport.query_params.merge!({
|
30
|
-
|
31
|
-
|
34
|
+
'Action' => 'download',
|
35
|
+
'downloadId' => @id})
|
32
36
|
@transport.execute_request
|
33
37
|
end
|
34
38
|
end
|
@@ -38,21 +42,22 @@ module Peddler
|
|
38
42
|
attr_writer :file_content
|
39
43
|
attr_accessor :batch, :download, :status, :type, :id, :submitted_at, :started_processing_at, :completed_processing_at, :messages_processed, :messages_successful, :messages_with_errors, :messages_with_warnings
|
40
44
|
|
45
|
+
MAPPED_PARAMS = {
|
46
|
+
'UploadStatus' => 'status',
|
47
|
+
'UploadType' => 'type',
|
48
|
+
'UploadId' => 'id',
|
49
|
+
'SubmittedDate' => 'submitted_at',
|
50
|
+
'StartedProcessingDate' => 'started_processing_at',
|
51
|
+
'CompletedProcessingDate' => 'completed_processing_at',
|
52
|
+
'CompletedProcesssingDate' => 'completed_processing_at',
|
53
|
+
'MessagesProcessed' => 'messages_processed',
|
54
|
+
'MessagesSuccessful' => 'messages_successful',
|
55
|
+
'MessagesWithErrors' => 'messages_with_errors',
|
56
|
+
'MessagesWithWarnings' => 'messages_with_warnings'}
|
57
|
+
|
41
58
|
def initialize(transport)
|
42
59
|
@transport = transport
|
43
60
|
@batch = []
|
44
|
-
@mapped_params = {
|
45
|
-
"UploadStatus" => "status",
|
46
|
-
"UploadType" => "type",
|
47
|
-
"UploadId" => "id",
|
48
|
-
"SubmittedDate" => "submitted_at",
|
49
|
-
"StartedProcessingDate" => "started_processing_at",
|
50
|
-
"CompletedProcessingDate" => "completed_processing_at",
|
51
|
-
"CompletedProcesssingDate" => "completed_processing_at",
|
52
|
-
"MessagesProcessed" => "messages_processed",
|
53
|
-
"MessagesSuccessful" => "messages_successful",
|
54
|
-
"MessagesWithErrors" => "messages_with_errors",
|
55
|
-
"MessagesWithWarnings" => "messages_with_warnings"}
|
56
61
|
end
|
57
62
|
|
58
63
|
# Returns content of the upload file.
|
@@ -72,11 +77,11 @@ module Peddler
|
|
72
77
|
|
73
78
|
# Uploads batch.
|
74
79
|
def upload
|
75
|
-
raise PeddlerError.new(
|
80
|
+
raise PeddlerError.new('Batch already uploaded') unless @id.nil?
|
76
81
|
@transport.modernize_request
|
77
82
|
@transport.query_params.merge!({
|
78
|
-
|
79
|
-
|
83
|
+
'Action' => 'upload',
|
84
|
+
'uploadType' => @type})
|
80
85
|
@transport.body = file_content
|
81
86
|
res = @transport.execute_request
|
82
87
|
process_response(res)
|
@@ -87,27 +92,25 @@ module Peddler
|
|
87
92
|
def <<(item)
|
88
93
|
@batch << item
|
89
94
|
end
|
90
|
-
|
95
|
+
|
96
|
+
private
|
97
|
+
|
91
98
|
def refresh_status
|
92
99
|
@transport.modernize_request
|
93
100
|
@transport.query_params.merge!({
|
94
|
-
|
95
|
-
|
101
|
+
'Action' => 'uploadStatus',
|
102
|
+
'uploadId' => @id})
|
96
103
|
res = @transport.execute_request
|
97
104
|
process_response(res)
|
98
105
|
end
|
99
106
|
|
100
107
|
def process_response(res)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
@download = Peddler::Feeds::Download.new(@transport, params[0])
|
108
|
-
else
|
109
|
-
self.send "#{@mapped_params[key]}=", value
|
110
|
-
end
|
108
|
+
upload = Hash.from_xml(res)['Response']['Upload'] || Hash.from_xml(res)['Response']['UploadsStatusList']['Upload']
|
109
|
+
upload.each_pair do |key, value|
|
110
|
+
if key == 'RelatedDownloadsList'
|
111
|
+
@download = Peddler::Feeds::Download.new(@transport, value['Download'])
|
112
|
+
else
|
113
|
+
self.send "#{MAPPED_PARAMS[key]}=", value
|
111
114
|
end
|
112
115
|
end
|
113
116
|
end
|
@@ -119,7 +122,7 @@ module Peddler
|
|
119
122
|
class Batch < Peddler::Feeds::Feed
|
120
123
|
def initialize(transport)
|
121
124
|
@file_header = "order-id\torder-item-id\tquantity\tship-date\tcarrier-code\tcarrier-name\ttracking-number\tship-method\r\n"
|
122
|
-
@type =
|
125
|
+
@type = '_POST_FLAT_FILE_FULFILLMENT_DATA_'
|
123
126
|
super(transport)
|
124
127
|
end
|
125
128
|
end
|
@@ -152,7 +155,7 @@ module Peddler
|
|
152
155
|
def initialize(transport)
|
153
156
|
@file_header = "TemplateType=OrderCancellation Version=1.0/1.0.3 This row for Amazon.com use only. Do not modify or delete.\r\n" +
|
154
157
|
"order-id\tcancellation-reason-code\tamazon-order-item-code\r\n"
|
155
|
-
@type =
|
158
|
+
@type = '_POST_FLAT_FILE_ORDER_ACKNOWLEDGEMENT_DATA_'
|
156
159
|
super(transport)
|
157
160
|
end
|
158
161
|
end
|
@@ -174,7 +177,7 @@ module Peddler
|
|
174
177
|
# Outputs a formatted line for the tab-delimited upload file.
|
175
178
|
def to_s
|
176
179
|
if @cancellation_reason_code.nil? != @amazon_order_item_code.nil?
|
177
|
-
raise PeddlerError.new(
|
180
|
+
raise PeddlerError.new('Provide codes for both cancellation reason and Amazon order item (or omit both).')
|
178
181
|
end
|
179
182
|
"#{@order_id}\t#{@cancellation_reason_code}\t#{@amazon_order_item_code}\r\n"
|
180
183
|
end
|
data/lib/peddler/handlers.rb
CHANGED
@@ -1,48 +1,24 @@
|
|
1
1
|
module Peddler
|
2
2
|
module Handlers
|
3
3
|
class XMLHandler
|
4
|
-
# Decodes an XML response.
|
5
|
-
def self.decode_response(res)
|
6
|
-
XmlSimple.xml_in(res)
|
7
|
-
end
|
8
|
-
# Parses responses to uploads and status queries for feeds in Section 7 of the docs. Walks
|
9
|
-
# through lists and returns an array of hashes.
|
10
|
-
def self.parse(name, xml)
|
11
|
-
name = name.to_s.capitalize
|
12
|
-
list = xml["#{name}sStatusList"] || xml["#{name}sList"]
|
13
|
-
if list
|
14
|
-
list.collect { |s| parse_status(name, s) }
|
15
|
-
else
|
16
|
-
[ parse_status(name, xml) ]
|
17
|
-
end
|
18
|
-
end
|
19
4
|
|
20
5
|
# Parses legacy responses to queries on statuses of generated reports and inventory uploads.
|
21
|
-
def self.parse_legacy(
|
22
|
-
if
|
23
|
-
|
24
|
-
elsif
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
28
|
-
protected
|
29
|
-
def self.parse_status(name, xml)
|
30
|
-
if xml[name]
|
31
|
-
xml[name][0].inject({}) do |memo, pair|
|
32
|
-
key, value = pair
|
33
|
-
value[0] = Time.parse(value[0]) if key =~ /Date$/
|
34
|
-
memo.merge!({ key => value[0] })
|
35
|
-
end
|
6
|
+
def self.parse_legacy(hash)
|
7
|
+
if hash['Batches']
|
8
|
+
hash['Batches']['Batch'].collect { |input| Peddler::LegacyReports::UploadStatus.new(input) }
|
9
|
+
elsif hash['Reports']
|
10
|
+
hash['Reports']['Report'].collect { |input| Peddler::LegacyReports::ReportStatus.new(input) }
|
36
11
|
end
|
37
12
|
end
|
38
13
|
end
|
39
14
|
|
40
15
|
class TabDelimitedHandler
|
41
|
-
# Decodes tab-delimited content into an array of OpenStruct objects.
|
16
|
+
# Decodes tab-delimited content into an array of OpenStruct objects. It
|
17
|
+
# assumes first line contains parameter names.
|
42
18
|
def self.decode_response(res)
|
43
19
|
lines = res.split("\n")
|
44
20
|
if lines.size > 1
|
45
|
-
params = lines[0].split("\t").collect{ |value| value.gsub(/-/,
|
21
|
+
params = lines[0].split("\t").collect{ |value| value.gsub(/-/, '_') }
|
46
22
|
params_size = params.size
|
47
23
|
(1..(lines.size - 1)).collect do |line_key|
|
48
24
|
values = lines[line_key].split("\t")
|
data/lib/peddler/inventory.rb
CHANGED
@@ -4,9 +4,13 @@ module Peddler
|
|
4
4
|
# Returns number of inventory uploads queued at Amazon
|
5
5
|
def self.count(transport)
|
6
6
|
transport.legacize_request
|
7
|
-
transport.path <<
|
7
|
+
transport.path << 'manual-reports/get-pending-uploads-count'
|
8
8
|
res = transport.execute_request
|
9
|
-
|
9
|
+
if res =~ /^<PendingUploadsCount>(.*)<\/PendingUploadsCount>$/
|
10
|
+
$1.to_i
|
11
|
+
else
|
12
|
+
nil
|
13
|
+
end
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
@@ -22,24 +26,27 @@ module Peddler
|
|
22
26
|
|
23
27
|
# Uploads batch to Amazon.
|
24
28
|
def upload(params={})
|
25
|
-
raise PeddlerError.new(
|
29
|
+
raise PeddlerError.new('Batch already uploaded') unless @id.nil?
|
26
30
|
@transport.legacize_request
|
27
|
-
@transport.path <<
|
31
|
+
@transport.path << 'catalog-upload/'
|
32
|
+
|
28
33
|
case params[:method].to_s
|
29
|
-
when
|
30
|
-
@transport.path <<
|
34
|
+
when 'modify'
|
35
|
+
@transport.path << 'modify-only'
|
31
36
|
@transport.body = file_content(:short)
|
32
|
-
when
|
33
|
-
@transport.path <<
|
37
|
+
when 'purge'
|
38
|
+
@transport.path << 'purge-replace'
|
34
39
|
@transport.body = file_content
|
35
40
|
else
|
36
|
-
@transport.path <<
|
41
|
+
@transport.path << 'add-modify-delete'
|
37
42
|
@transport.body = file_content
|
38
43
|
end
|
39
44
|
params.delete(:method)
|
45
|
+
|
40
46
|
params = defaultize(params)
|
41
47
|
@transport.headers.merge!(params)
|
42
48
|
res = @transport.execute_request
|
49
|
+
|
43
50
|
if res =~ /^<BatchID>(.*)<\/BatchID>$/
|
44
51
|
@id = $1
|
45
52
|
else
|
@@ -48,26 +55,8 @@ module Peddler
|
|
48
55
|
true
|
49
56
|
end
|
50
57
|
|
51
|
-
#
|
52
|
-
def defaultize(params)
|
53
|
-
{ :upload_for => "Marketplace",
|
54
|
-
:file_format =>"TabDelimited",
|
55
|
-
:asin_match_create => "Y",
|
56
|
-
:asinate => "Y",
|
57
|
-
:batch_id => "Y",
|
58
|
-
:email => "Y"}.each_pair{ |key, value| params[key] = value unless params[key] }
|
59
|
-
# Some Amazon dimwit figured he'd spell this differently
|
60
|
-
if params[:enable_expedited_shipping]
|
61
|
-
params["enable-expedited-shipping"] = params[:enable_expedited_shipping]
|
62
|
-
params.delete(:enable_expedited_shipping)
|
63
|
-
else
|
64
|
-
params["enable-expedited-shipping"] = "Y"
|
65
|
-
end
|
66
|
-
params
|
67
|
-
end
|
68
|
-
|
58
|
+
# Returns upload file string.
|
69
59
|
def file_content(type=:long)
|
70
|
-
return @file_content if @file_content
|
71
60
|
case type
|
72
61
|
when :long
|
73
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"
|
@@ -76,20 +65,63 @@ module Peddler
|
|
76
65
|
out = "sku\tprice\tquantity\r\n"
|
77
66
|
@batch.each{ |item| out << item.to_s(:short) }
|
78
67
|
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
def file_content=(file_content)
|
83
|
-
@file_content = file_content
|
68
|
+
out
|
84
69
|
end
|
85
|
-
|
70
|
+
|
71
|
+
# Adds an item to inventory.
|
86
72
|
def <<(item)
|
87
73
|
@batch << item
|
88
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
|
89
98
|
end
|
90
99
|
|
100
|
+
# This is an inventory item.
|
91
101
|
class Item
|
92
|
-
attr_accessor :product_id,
|
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
|
93
125
|
|
94
126
|
def initialize(params={})
|
95
127
|
params.each_pair{ |key, value| send("#{key.to_s}=", value) }
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Peddler
|
2
|
+
|
2
3
|
# This module contains methods to manage legacy reports -- anything that comes before section 7 in the API docs.
|
3
4
|
module LegacyReports
|
5
|
+
|
4
6
|
# Returns statuses of most recent reports in an array of OpenStructs.
|
5
7
|
def self.latest(transport,name,params={})
|
6
8
|
transport.legacize_request
|
@@ -13,8 +15,7 @@ module Peddler
|
|
13
15
|
transport.headers[:number_of_reports] = params[:count] if params[:count]
|
14
16
|
end
|
15
17
|
res = transport.execute_request
|
16
|
-
|
17
|
-
Peddler::Handlers::XMLHandler.parse_legacy(xml)
|
18
|
+
Peddler::Handlers::XMLHandler.parse_legacy(Hash.from_xml(res))
|
18
19
|
end
|
19
20
|
|
20
21
|
# Requests a report to be generated and returns the report instance if request is successful.
|
data/lib/peddler/reports.rb
CHANGED
@@ -1,28 +1,32 @@
|
|
1
1
|
module Peddler
|
2
|
+
|
2
3
|
# This module generates and downloads unshipped order reports.
|
3
|
-
# I decided to keep this out of Peddler::LegacyReports because the API is
|
4
|
+
# I decided to keep this out of Peddler::LegacyReports because the API is
|
5
|
+
# quite different.
|
4
6
|
module Reports
|
5
|
-
|
6
|
-
# It
|
7
|
+
|
8
|
+
# This is an unshipped orders report. It is very similar to the feed
|
9
|
+
# objects, so I'm just porting over the class.
|
7
10
|
class UnshippedOrdersReport < Peddler::Feeds::Feed
|
8
11
|
alias :unshipped_orders :batch
|
9
12
|
attr_accessor :starts_at, :ends_at, :scheduled
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
MAPPED_PARAMS = {
|
15
|
+
"ReportID" => "id",
|
16
|
+
"StartDate" => "starts_at",
|
17
|
+
"EndDate" => "ends_at",
|
18
|
+
"DownloadType" => "type",
|
19
|
+
"Scheduled" => "scheduled",
|
20
|
+
"ReportStatus" => "status",
|
21
|
+
"SubmittedDate" => "submitted_at",
|
22
|
+
"StartedProcessingDate" => "started_processing_at",
|
23
|
+
"CompletedProcessingDate" => "completed_processing_at",
|
24
|
+
"CompletedProcesssingDate" => "completed_processing_at"}
|
25
|
+
|
26
|
+
# Creates new unshipped order report. It will send a request to
|
27
|
+
# Amazon to generate the report if the report ID is not already set.
|
13
28
|
def initialize(transport, params={})
|
14
29
|
super(transport)
|
15
|
-
@mapped_params = {
|
16
|
-
"ReportID" => "id",
|
17
|
-
"StartDate" => "starts_at",
|
18
|
-
"EndDate" => "ends_at",
|
19
|
-
"DownloadType" => "type",
|
20
|
-
"Scheduled" => "scheduled",
|
21
|
-
"ReportStatus" => "status",
|
22
|
-
"SubmittedDate" => "submitted_at",
|
23
|
-
"StartedProcessingDate" => "started_processing_at",
|
24
|
-
"CompletedProcessingDate" => "completed_processing_at",
|
25
|
-
"CompletedProcesssingDate" => "completed_processing_at"}
|
26
30
|
params.each_pair{ |key, value| self.send "#{key}=", value }
|
27
31
|
@starts_at ||= (Date.today - 7).strftime("%Y-%m-%dT00:00:00-00:00")
|
28
32
|
@ends_at ||= (Date.today + 1).strftime("%Y-%m-%dT00:00:00-00:00")
|
@@ -33,7 +37,9 @@ module Peddler
|
|
33
37
|
end
|
34
38
|
self
|
35
39
|
end
|
36
|
-
|
40
|
+
|
41
|
+
private
|
42
|
+
|
37
43
|
def refresh_status
|
38
44
|
@transport.modernize_request
|
39
45
|
@transport.query_params.merge!({
|
@@ -55,17 +61,14 @@ module Peddler
|
|
55
61
|
end
|
56
62
|
|
57
63
|
def process_response(res)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
else
|
67
|
-
self.send "#{@mapped_params[key]}=", value
|
68
|
-
end
|
64
|
+
hash = Hash.from_xml(res)
|
65
|
+
hash['Response']['Report'].each_pair do |key, value|
|
66
|
+
if key == "ListOfDownloads"
|
67
|
+
params = Peddler::Handlers::XMLHandler.parse(:download, value)
|
68
|
+
@download = Peddler::Feeds::Download.new(@transport, value['Download'])
|
69
|
+
@batch = Peddler::Handlers::TabDelimitedHandler.decode_response(@download.to_s)
|
70
|
+
else
|
71
|
+
self.send "#{MAPPED_PARAMS[key]}=", value
|
69
72
|
end
|
70
73
|
end
|
71
74
|
end
|
data/lib/peddler.rb
CHANGED
@@ -1,25 +1,19 @@
|
|
1
1
|
# Peddler is a Ruby wrapper to the Amazon Inventory management API.
|
2
2
|
module Peddler
|
3
|
-
VERSION =
|
3
|
+
VERSION = '0.2.0'
|
4
4
|
end
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
require "net/https"
|
13
|
-
require "ostruct"
|
14
|
-
require "tempfile"
|
15
|
-
require "time"
|
16
|
-
require "xmlsimple"
|
6
|
+
require 'net/https'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'tempfile'
|
9
|
+
require 'time'
|
10
|
+
require 'active_support'
|
17
11
|
|
18
|
-
require File.dirname(__FILE__) +
|
19
|
-
require File.dirname(__FILE__) +
|
20
|
-
require File.dirname(__FILE__) +
|
21
|
-
require File.dirname(__FILE__) +
|
22
|
-
require File.dirname(__FILE__) +
|
23
|
-
require File.dirname(__FILE__) +
|
24
|
-
require File.dirname(__FILE__) +
|
25
|
-
require File.dirname(__FILE__) +
|
12
|
+
require File.dirname(__FILE__) + '/peddler/client'
|
13
|
+
require File.dirname(__FILE__) + '/peddler/handlers'
|
14
|
+
require File.dirname(__FILE__) + '/peddler/feeds'
|
15
|
+
require File.dirname(__FILE__) + '/peddler/inventory'
|
16
|
+
require File.dirname(__FILE__) + '/peddler/legacy_reports'
|
17
|
+
require File.dirname(__FILE__) + '/peddler/refunds'
|
18
|
+
require File.dirname(__FILE__) + '/peddler/reports'
|
19
|
+
require File.dirname(__FILE__) + '/peddler/transport'
|
data/peddler.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{peddler}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Hakan
|
12
|
-
s.date = %q{
|
11
|
+
s.authors = ["Hakan \305\236enol Ensari"]
|
12
|
+
s.date = %q{2010-01-11}
|
13
13
|
s.description = %q{Peddler is a Ruby wrapper to the Amazon Inventory Management API.}
|
14
14
|
s.email = %q{hakan.ensari@papercavalier.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -66,15 +66,15 @@ Gem::Specification.new do |s|
|
|
66
66
|
s.specification_version = 3
|
67
67
|
|
68
68
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
69
|
-
s.add_runtime_dependency(%q<
|
70
|
-
s.add_development_dependency(%q<rspec>, [">=
|
69
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
70
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
71
71
|
else
|
72
|
-
s.add_dependency(%q<
|
73
|
-
s.add_dependency(%q<rspec>, [">=
|
72
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
73
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
74
74
|
end
|
75
75
|
else
|
76
|
-
s.add_dependency(%q<
|
77
|
-
s.add_dependency(%q<rspec>, [">=
|
76
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
77
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
data/spec/peddler/feeds_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__),
|
1
|
+
require File.join(File.dirname(__FILE__), '/../spec_helper')
|
2
2
|
|
3
3
|
module Peddler
|
4
4
|
module Feeds
|
@@ -8,39 +8,39 @@ module Peddler
|
|
8
8
|
@transport = Peddler::Transport.new
|
9
9
|
@transport.modernize_request
|
10
10
|
@feed = Peddler::Feeds::OrderFulfillment::Batch.new(@transport)
|
11
|
-
@fulfilled_order = Peddler::Feeds::OrderFulfillment::Item.new :order_id =>
|
12
|
-
:ship_date => Date.parse(
|
11
|
+
@fulfilled_order = Peddler::Feeds::OrderFulfillment::Item.new :order_id => '123-1234567-1234567',
|
12
|
+
:ship_date => Date.parse('2009-08-11').to_s
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'should add items to batch' do
|
16
16
|
@feed.batch.size.should == 0
|
17
17
|
@feed << @fulfilled_order
|
18
18
|
@feed.batch.size.should == 1
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'should create content for upload' do
|
22
22
|
@feed << @fulfilled_order
|
23
23
|
@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"
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
26
|
+
it 'should upload' do
|
27
27
|
@feed.id.should == nil
|
28
|
-
@transport.stub!(:execute_request).and_return('
|
28
|
+
@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>')
|
29
29
|
@feed.upload
|
30
|
-
@feed.id.should ==
|
31
|
-
@feed.status.should ==
|
30
|
+
@feed.id.should == '130895733'
|
31
|
+
@feed.status.should == '_SUBMITTED_'
|
32
32
|
end
|
33
33
|
|
34
|
-
it
|
35
|
-
@transport.stub!(:execute_request).and_return('
|
34
|
+
it 'should refresh status' do
|
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
36
|
@feed.upload
|
37
|
-
@transport.stub!(:execute_request).and_return('
|
38
|
-
@feed.status.should ==
|
39
|
-
@feed.status!.should ==
|
40
|
-
@transport.stub!(:execute_request).and_return('
|
41
|
-
@feed.status!.should ==
|
42
|
-
@feed.download.id.should ==
|
43
|
-
@feed.download.available_at.
|
37
|
+
@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>')
|
38
|
+
@feed.status.should == '_SUBMITTED_'
|
39
|
+
@feed.status!.should == '_IN_PROGRESS_'
|
40
|
+
@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>')
|
41
|
+
@feed.status!.should == '_DONE_'
|
42
|
+
@feed.download.id.should == '3404021'
|
43
|
+
@feed.download.available_at.should == '2009-04-24T23:47:24+00:00'
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -51,27 +51,27 @@ module Peddler
|
|
51
51
|
@transport = Peddler::Transport.new
|
52
52
|
@transport.modernize_request
|
53
53
|
@feed = Peddler::Feeds::OrderCancellation::Batch.new(@transport)
|
54
|
-
@cancelled_order = Peddler::Feeds::OrderCancellation::Item.new :order_id =>
|
54
|
+
@cancelled_order = Peddler::Feeds::OrderCancellation::Item.new :order_id => '123-1234567-1234567'
|
55
55
|
end
|
56
56
|
|
57
|
-
it
|
57
|
+
it 'should add items to batch' do
|
58
58
|
@feed.batch.size.should == 0
|
59
59
|
@feed << @cancelled_order
|
60
60
|
@feed.batch.size.should == 1
|
61
61
|
end
|
62
62
|
|
63
|
-
it
|
63
|
+
it 'should create content for upload' do
|
64
64
|
@feed << @cancelled_order
|
65
65
|
@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"
|
66
66
|
end
|
67
67
|
|
68
|
-
it
|
69
|
-
@cancelled_order.cancellation_reason_code =
|
68
|
+
it 'should raise error if cancellation reason code is given but Amazon order item code is missing' do
|
69
|
+
@cancelled_order.cancellation_reason_code = 'BuyerCanceled'
|
70
70
|
lambda { @cancelled_order.to_s }.should raise_error(PeddlerError)
|
71
71
|
end
|
72
72
|
|
73
|
-
it
|
74
|
-
@cancelled_order.amazon_order_item_code =
|
73
|
+
it 'should raise error if Amazon order item code is given but cancellation reason code is missing' do
|
74
|
+
@cancelled_order.amazon_order_item_code = '111111111111'
|
75
75
|
lambda { @cancelled_order.to_s }.should raise_error(PeddlerError)
|
76
76
|
end
|
77
77
|
end
|
@@ -1,18 +1,11 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "/../spec_helper")
|
2
|
+
|
2
3
|
module Peddler
|
3
|
-
module Handlers
|
4
|
-
describe XMLHandler do
|
5
|
-
it "should parse XML" do
|
6
|
-
xml = Peddler::Handlers::XMLHandler.decode_response("<Reports> <Report>reportstarttime=08-13-2009:06-16-06 reportendtime=12-31-1969:16-00-00 reportid=2599221990 </Report></Reports>")
|
7
|
-
statuses = Peddler::Handlers::XMLHandler.parse_legacy(xml)
|
8
|
-
statuses[0].id.should == "2599221990"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
4
|
+
module Handlers
|
12
5
|
describe TabDelimitedHandler do
|
13
6
|
it "should parse tab-delimited text" do
|
14
7
|
text = Peddler::Handlers::TabDelimitedHandler.decode_response("title\tautor\nA Thousand Plateaus\tGilles Deleuze\n")
|
15
|
-
text[0].title.should ==
|
8
|
+
text[0].title.should == 'A Thousand Plateaus'
|
16
9
|
end
|
17
10
|
end
|
18
11
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__),
|
1
|
+
require File.join(File.dirname(__FILE__), '/../spec_helper')
|
2
2
|
|
3
3
|
module Peddler
|
4
4
|
|
@@ -6,10 +6,10 @@ module Peddler
|
|
6
6
|
|
7
7
|
describe Queue do
|
8
8
|
|
9
|
-
it
|
9
|
+
it 'should show queue count' do
|
10
10
|
transport = Peddler::Transport.new
|
11
11
|
transport.legacize_request
|
12
|
-
transport.stub!(:execute_request).and_return(
|
12
|
+
transport.stub!(:execute_request).and_return('<PendingUploadsCount>1</PendingUploadsCount>')
|
13
13
|
Peddler::Inventory::Queue.count(transport).should == 1
|
14
14
|
end
|
15
15
|
|
@@ -21,47 +21,49 @@ module Peddler
|
|
21
21
|
@transport = Peddler::Transport.new
|
22
22
|
@transport.legacize_request
|
23
23
|
@inventory = Peddler::Inventory::Batch.new(@transport)
|
24
|
-
@item = Peddler::Inventory::Item.new :product_id =>
|
24
|
+
@item = Peddler::Inventory::Item.new :product_id => '1234567890',
|
25
25
|
:price => 100.00,
|
26
|
-
:sku =>
|
26
|
+
:sku => 'FOO-SKU',
|
27
27
|
:quantity => 10
|
28
28
|
end
|
29
29
|
|
30
|
-
it
|
30
|
+
it 'should add items to batch' do
|
31
31
|
@inventory.batch.size.should == 0
|
32
32
|
@inventory << @item
|
33
33
|
@inventory.batch.size.should == 1
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
36
|
+
it 'should generate an upload file' do
|
37
37
|
@inventory << @item
|
38
38
|
@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"
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'should generate a modify-only upload file' do
|
42
42
|
@inventory << @item
|
43
43
|
@inventory.file_content(:short).should == "sku\tprice\tquantity\r\nFOO-SKU\t100.0\t10\r\n"
|
44
44
|
end
|
45
45
|
|
46
|
-
it
|
47
|
-
params = @inventory.defaultize
|
48
|
-
|
46
|
+
it 'should generate default headers for uploading' do
|
47
|
+
params = @inventory.send(:defaultize,
|
48
|
+
:file_format => 'UIEE',
|
49
|
+
:enable_expedited_shipping => 'N'
|
50
|
+
)
|
49
51
|
params[:method].should be_nil
|
50
|
-
params[:upload_for].should ==
|
51
|
-
params[:email].should ==
|
52
|
-
params[:file_format].should ==
|
53
|
-
params[
|
52
|
+
params[:upload_for].should == 'Marketplace'
|
53
|
+
params[:email].should == 'Y'
|
54
|
+
params[:file_format].should == 'UIEE'
|
55
|
+
params['enable-expedited-shipping'].should == 'N'
|
54
56
|
params[:enable_expedited_shipping].should be_nil
|
55
57
|
end
|
56
58
|
|
57
|
-
it
|
58
|
-
@transport.stub!(:execute_request).and_return(
|
59
|
+
it 'should upload batch' do
|
60
|
+
@transport.stub!(:execute_request).and_return('<BatchID>2585199250</BatchID>')
|
59
61
|
@inventory.upload.should == true
|
60
|
-
@inventory.id.should ==
|
62
|
+
@inventory.id.should == '2585199250'
|
61
63
|
end
|
62
64
|
|
63
|
-
it
|
64
|
-
@transport.stub!(:execute_request).and_return(
|
65
|
+
it 'should raise error if a subsequent upload is attempted' do
|
66
|
+
@transport.stub!(:execute_request).and_return('<BatchID>2585199250</BatchID>')
|
65
67
|
@inventory.upload.should == true
|
66
68
|
@inventory.id.should_not == nil
|
67
69
|
lambda { @inventory.upload }.should raise_error(PeddlerError)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__),
|
1
|
+
require File.join(File.dirname(__FILE__), '/../spec_helper')
|
2
2
|
|
3
3
|
module Peddler
|
4
4
|
describe LegacyReports do
|
@@ -7,28 +7,28 @@ module Peddler
|
|
7
7
|
@transport.legacize_request
|
8
8
|
end
|
9
9
|
|
10
|
-
it
|
11
|
-
@transport.stub!(:execute_request).and_return(
|
10
|
+
it 'should generate an order report' do
|
11
|
+
@transport.stub!(:execute_request).and_return('<Status>SUCCESS</Status>')
|
12
12
|
res = Peddler::LegacyReports.generate(@transport, :order, :number_of_days => 30)
|
13
13
|
res.should be_an_instance_of(Peddler::LegacyReports::Report)
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
17
|
-
@transport.stub!(:execute_request).and_return(
|
16
|
+
it 'should show most recent order reports' do
|
17
|
+
@transport.stub!(:execute_request).and_return('<Reports> <Report>reportstarttime=12-26-2009:19-00-02 reportendtime=01-10-2010:19-00-02 reportid=2893717072 </Report><Report>reportstarttime=01-10-2010:14-00-00 reportendtime=01-10-2010:18-00-00 reportid=2893636754 </Report><Report>reportstarttime=12-26-2009:18-00-01 reportendtime=01-10-2010:18-00-01 reportid=2893629784 </Report><Report>reportstarttime=12-26-2009:17-00-07 reportendtime=01-10-2010:17-00-07 reportid=2893548356 </Report><Report>reportstarttime=12-26-2009:16-00-02 reportendtime=01-10-2010:16-00-02 reportid=2893461740 </Report><Report>reportstarttime=12-26-2009:15-00-02 reportendtime=01-10-2010:15-00-02 reportid=2893375352 </Report><Report>reportstarttime=01-10-2010:10-00-00 reportendtime=01-10-2010:14-00-00 reportid=2893291418 </Report><Report>reportstarttime=12-26-2009:14-00-02 reportendtime=01-10-2010:14-00-02 reportid=2893283538 </Report><Report>reportstarttime=12-26-2009:13-00-02 reportendtime=01-10-2010:13-00-02 reportid=2893197830 </Report><Report>reportstarttime=12-26-2009:12-00-02 reportendtime=01-10-2010:12-00-02 reportid=2893112598 </Report></Reports>')
|
18
18
|
report_status = Peddler::LegacyReports.latest(@transport, :order, :count => 1)[0]
|
19
|
-
report_status.starts_at.should ==
|
20
|
-
report_status.id.should ==
|
19
|
+
report_status.starts_at.should == '12-26-2009:19-00-02'
|
20
|
+
report_status.id.should == '2893717072'
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
24
|
-
@transport.stub!(:execute_request).and_return(
|
23
|
+
it 'should show most recent uploads' do
|
24
|
+
@transport.stub!(:execute_request).and_return('<Batches> <Batch>batchid=2586376232 status=Done dateandtime=08/07/2009 01:48:23 PDT activateditems=1020 numberofwarnings=0 itemsnotacivated=0 </Batch></Batches>')
|
25
25
|
upload = Peddler::LegacyReports.latest(@transport, :upload, :count => 1)[0]
|
26
|
-
upload.id.should ==
|
27
|
-
upload.status.should ==
|
28
|
-
upload.datetime.should ==
|
29
|
-
upload.activated_items.should ==
|
30
|
-
upload.number_of_warnings.should ==
|
31
|
-
upload.items_not_activated.should ==
|
26
|
+
upload.id.should == '2586376232'
|
27
|
+
upload.status.should == 'Done'
|
28
|
+
upload.datetime.should == '08/07/2009 01:48:23 PDT'
|
29
|
+
upload.activated_items.should == '1020'
|
30
|
+
upload.number_of_warnings.should == '0'
|
31
|
+
upload.items_not_activated.should == '0'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -40,46 +40,46 @@ module Peddler
|
|
40
40
|
@report = Peddler::LegacyReports::Report.new(@transport)
|
41
41
|
end
|
42
42
|
|
43
|
-
it
|
43
|
+
it 'should download an inventory upload error log' do
|
44
44
|
@transport.stub!(:execute_request).and_return("Feed Processing Summary:\n\tNumber of records processed\t\t82\n\tNumber of records successful\t\t81\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n27\t1111111111\t8026\tError\tSeller is not authorized to list products in this category. For more details, see http://sellercentral.amazon.com/gp/errorcode/8026\n")
|
45
45
|
|
46
46
|
@report.name = :upload
|
47
|
-
@report.id =
|
47
|
+
@report.id = '1234567890'
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
50
|
+
it 'should download an inventory upload error log' do
|
51
51
|
@transport.stub!(:execute_request).and_return("Feed Processing Summary:\n\tNumber of records processed\t\t82\n\tNumber of records successful\t\t81\n\noriginal-record-number\tsku\terror-code\terror-type\terror-message\n27\t1111111111\t8026\tError\tSeller is not authorized to list products in this category. For more details, see http://sellercentral.amazon.com/gp/errorcode/8026\n")
|
52
52
|
@report.name = :upload
|
53
|
-
@report.id =
|
53
|
+
@report.id = '1234567890'
|
54
54
|
@report.body.should =~ /Feed Processing Summary/
|
55
55
|
end
|
56
56
|
|
57
|
-
it
|
57
|
+
it 'should retrieve an order report by id' do
|
58
58
|
@transport.stub!(:execute_request).and_return("payments-status\torder-id\torder-item-id\tpayments-date\tpayments-transaction-id\titem-name\tlisting-id\tsku\tprice\tshipping-fee\tquantity-purchased\ttotal-price\tpurchase-date\tbatch-id\tbuyer-email\tbuyer-name\trecipient-name\tship-address-1\tship-address-2\tship-city\tship-state\tship-zip\tship-country\tspecial-comments\tupc\tship-method\n\t001-1234567-1234567\t12345678901234\t2009-07-23 08:59:03 PST\t\tFoo Bar\t000000000000\t1234567890\t10.00\t3.99\t1\t13.99\t2009-07-23 08:59:03 PST\t\tfoo@bar.com\tJOHN DOE\tJohn Doe\t1 MAIN ST\t\tNEW YORK\tNY\t10001-1000\tUS\t\t\tstandard\n")
|
59
59
|
@report.name = :order
|
60
|
-
@report.id =
|
60
|
+
@report.id = '1234567890'
|
61
61
|
res = Peddler::Handlers::TabDelimitedHandler.decode_response(@report.body)
|
62
62
|
res.size.should == 1
|
63
|
-
res[0].order_id.should ==
|
64
|
-
res[0].buyer_name.should ==
|
63
|
+
res[0].order_id.should == '001-1234567-1234567'
|
64
|
+
res[0].buyer_name.should == 'JOHN DOE'
|
65
65
|
end
|
66
66
|
|
67
|
-
it
|
67
|
+
it 'should retrieve an order report by report name' do
|
68
68
|
@transport.stub!(:execute_request).and_return("payments-status\torder-id\torder-item-id\tpayments-date\tpayments-transaction-id\titem-name\tlisting-id\tsku\tprice\tshipping-fee\tquantity-purchased\ttotal-price\tpurchase-date\tbatch-id\tbuyer-email\tbuyer-name\trecipient-name\tship-address-1\tship-address-2\tship-city\tship-state\tship-zip\tship-country\tspecial-comments\tupc\tship-method\n\t001-1234567-1234567\t12345678901234\t2009-07-23 08:59:03 PST\t\tFoo Bar\t000000000000\t1234567890\t10.00\t3.99\t1\t13.99\t2009-07-23 08:59:03 PST\t\tfoo@bar.com\tJOHN DOE\tJohn Doe\t1 MAIN ST\t\tNEW YORK\tNY\t10001-1000\tUS\t\t\tstandard\n")
|
69
69
|
@report.name = :order
|
70
70
|
res = Peddler::Handlers::TabDelimitedHandler.decode_response(@report.body)
|
71
71
|
res.size.should == 1
|
72
|
-
res[0].order_id.should ==
|
73
|
-
res[0].buyer_name.should ==
|
72
|
+
res[0].order_id.should == '001-1234567-1234567'
|
73
|
+
res[0].buyer_name.should == 'JOHN DOE'
|
74
74
|
end
|
75
75
|
|
76
|
-
it
|
76
|
+
it 'should retrieve an open listings liter report by id' do
|
77
77
|
@transport.stub!(:execute_request).and_return("seller-sku\tquantity\nSKU-FOO\t14\n")
|
78
78
|
@report.name = :open_listings_liter
|
79
|
-
@report.id =
|
79
|
+
@report.id = '1234567890'
|
80
80
|
res = Peddler::Handlers::TabDelimitedHandler.decode_response(@report.body)
|
81
81
|
res.size.should == 1
|
82
|
-
res[0].seller_sku.should ==
|
82
|
+
res[0].seller_sku.should == 'SKU-FOO'
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
metadata
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peddler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Hakan
|
7
|
+
- "Hakan \xC5\x9Eenol Ensari"
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-11 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: activesupport
|
17
17
|
type: :runtime
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 2.3.5
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.2.9
|
34
34
|
version:
|
35
35
|
description: Peddler is a Ruby wrapper to the Amazon Inventory Management API.
|
36
36
|
email: hakan.ensari@papercavalier.com
|