snl-peddler 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/History.txt +2 -0
- data/LICENSE +22 -0
- data/README.rdoc +104 -0
- data/Rakefile +17 -0
- data/VERSION.yml +4 -0
- data/lib/peddler.rb +25 -0
- data/lib/peddler/client.rb +240 -0
- data/lib/peddler/feeds.rb +181 -0
- data/lib/peddler/handlers.rb +58 -0
- data/lib/peddler/inventory.rb +108 -0
- data/lib/peddler/legacy_reports.rb +107 -0
- data/lib/peddler/refunds.rb +54 -0
- data/lib/peddler/reports.rb +94 -0
- data/lib/peddler/transport.rb +135 -0
- data/peddler.gemspec +78 -0
- data/spec/peddler/client_spec.rb +47 -0
- data/spec/peddler/feeds_spec.rb +70 -0
- data/spec/peddler/handlers_spec.rb +15 -0
- data/spec/peddler/inventory_spec.rb +74 -0
- data/spec/peddler/legacy_reports_spec.rb +86 -0
- data/spec/peddler/refunds_spec.rb +35 -0
- data/spec/peddler/reports_spec.rb +19 -0
- data/spec/peddler/transport_spec.rb +58 -0
- data/spec/spec_helper.rb +3 -0
- metadata +106 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.DS_Store
|
data/History.txt
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2009 Hakan Şenol Ensari
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
= Peddler
|
2
|
+
|
3
|
+
Peddler is a Ruby wrapper to the Amazon Inventory management API.
|
4
|
+
|
5
|
+
== Example usage
|
6
|
+
|
7
|
+
Fire off a client:
|
8
|
+
|
9
|
+
client = Peddler::Client.new(
|
10
|
+
:username => "foo@bar.com",
|
11
|
+
:password => "secret",
|
12
|
+
:region => "us")
|
13
|
+
|
14
|
+
Create an inventory file:
|
15
|
+
|
16
|
+
batch = client.new_inventory_batch
|
17
|
+
item = client.new_inventory_item(
|
18
|
+
:product_id => "1234567890",
|
19
|
+
:price => 100.00,
|
20
|
+
:sku => "SKU-123",
|
21
|
+
:quantity => 10)
|
22
|
+
batch << item
|
23
|
+
...
|
24
|
+
|
25
|
+
Repeat ad infinitum and then upload:
|
26
|
+
|
27
|
+
batch.upload
|
28
|
+
|
29
|
+
The batch now should have an upload ID assigned to it. Let's check its error log.
|
30
|
+
|
31
|
+
upload_log = client.new_report(
|
32
|
+
:upload,
|
33
|
+
:id => batch.id)
|
34
|
+
upload_log.body
|
35
|
+
=> "Feed Processing Summary:\n\tNumber of records processed\t\t1\n\tNumber of records successful\t\t1\n\n"
|
36
|
+
|
37
|
+
You're done uploading your inventory and now want to download some reports from Amazon. Let's go ahead and fetch a preorder list for the past two days to see if there is anything you can fill:
|
38
|
+
|
39
|
+
preorders_report = client.new_report(
|
40
|
+
:preorder,
|
41
|
+
:product_line => "Books",
|
42
|
+
:frequency => 2)
|
43
|
+
preorders = Peddler::Handlers::TabDelimitedHandler.decode_response(preorders_report.body)
|
44
|
+
p preorders.size
|
45
|
+
=> 2000
|
46
|
+
p preorders[0].asin
|
47
|
+
=> "1234567890"
|
48
|
+
p preorders[0].average_asking_price
|
49
|
+
=> "100"
|
50
|
+
|
51
|
+
Maybe you're probably wondering if you have any new orders:
|
52
|
+
|
53
|
+
orders_report = client.new_report :order
|
54
|
+
orders = Peddler::Handlers::TabDelimitedHandler.decode_response(orders_report.body)
|
55
|
+
p orders.size
|
56
|
+
=> 1500
|
57
|
+
p orders[0].item_name
|
58
|
+
=> "A Thousand Plateaus: Capitalism and Schizophrenia (Paperback) by Gilles Deleuze"
|
59
|
+
|
60
|
+
You have processed the orders and want to post back the results to Amazon, now that they're "charge when ship." Let's start with sending shipment info:
|
61
|
+
|
62
|
+
feed = client.new_order_fulfillment_feed
|
63
|
+
fulfilled_order = new_fulfilled_order(
|
64
|
+
:order_id => "123-1234567-1234567",
|
65
|
+
:order_date => "2009-08-01",
|
66
|
+
:carrier_code => "USPS",
|
67
|
+
:tracking_number => "0308 0330 0000 0000 0000")
|
68
|
+
feed << fulfilled_order
|
69
|
+
|
70
|
+
Again, repeat until done and upload:
|
71
|
+
|
72
|
+
feed.upload
|
73
|
+
|
74
|
+
Curious to see the processing report?
|
75
|
+
|
76
|
+
p feed.status
|
77
|
+
=> "_SUBMITTED_"
|
78
|
+
|
79
|
+
Refresh until you see:
|
80
|
+
|
81
|
+
p feed.status!
|
82
|
+
=> "_DONE_"
|
83
|
+
|
84
|
+
Finally, check the report:
|
85
|
+
|
86
|
+
p feed.download.to_s
|
87
|
+
=> ...
|
88
|
+
|
89
|
+
Sadly, you also have an order you can't fulfill. No problem. The workflow is quite similar:
|
90
|
+
|
91
|
+
feed = client.new_order_cancellation_feed
|
92
|
+
cancelled_order = new_cancelled_order(
|
93
|
+
:order_id => "123-1234567-1234567")
|
94
|
+
feed << cancelled_order
|
95
|
+
feed.upload
|
96
|
+
sleep(60)
|
97
|
+
feed.status!
|
98
|
+
=> "_DONE_"
|
99
|
+
p feed.download.to_s
|
100
|
+
=> ...
|
101
|
+
|
102
|
+
Run rdoc and check the source for more detailed info.
|
103
|
+
|
104
|
+
Copyright © 2009 Hakan Senol Ensari, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
begin
|
4
|
+
require "jeweler"
|
5
|
+
Jeweler::Tasks.new do |s|
|
6
|
+
s.name = "peddler"
|
7
|
+
s.summary = "Peddler is a Ruby wrapper to the Amazon Inventory Management API."
|
8
|
+
s.email = "hakan.ensari@papercavalier.com"
|
9
|
+
s.homepage = "http://github.com/snl/peddler"
|
10
|
+
s.description = "Peddler is a Ruby wrapper to the Amazon Inventory Management API."
|
11
|
+
s.authors = ["Hakan Senol Ensari"]
|
12
|
+
s.add_dependency "xmlsimple"
|
13
|
+
s.add_development_dependency "rspec"
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
17
|
+
end
|
data/VERSION.yml
ADDED
data/lib/peddler.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Peddler is a Ruby wrapper to the Amazon Inventory management API.
|
2
|
+
module Peddler
|
3
|
+
VERSION = "0.1"
|
4
|
+
end
|
5
|
+
|
6
|
+
class String #:nodoc: all
|
7
|
+
def camelize
|
8
|
+
self.gsub(/(^|_)(.)/) { $2.upcase }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require "net/https"
|
13
|
+
require "ostruct"
|
14
|
+
require "tempfile"
|
15
|
+
require "time"
|
16
|
+
require "xmlsimple"
|
17
|
+
|
18
|
+
require File.dirname(__FILE__) + "/peddler/client"
|
19
|
+
require File.dirname(__FILE__) + "/peddler/handlers"
|
20
|
+
require File.dirname(__FILE__) + "/peddler/feeds"
|
21
|
+
require File.dirname(__FILE__) + "/peddler/inventory"
|
22
|
+
require File.dirname(__FILE__) + "/peddler/legacy_reports"
|
23
|
+
require File.dirname(__FILE__) + "/peddler/refunds"
|
24
|
+
require File.dirname(__FILE__) + "/peddler/reports"
|
25
|
+
require File.dirname(__FILE__) + "/peddler/transport"
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# = Peddler
|
2
|
+
# Peddler is a Ruby wrapper to the Amazon Inventory management API.
|
3
|
+
#
|
4
|
+
# Peddler::Client has some detailed explanation and examples of usage.
|
5
|
+
module Peddler
|
6
|
+
# This is the public interface of the Peddler library.
|
7
|
+
class Client
|
8
|
+
# Creates a client instance.
|
9
|
+
#
|
10
|
+
# client = Peddler::Client.new :username => "foo@bar.com",
|
11
|
+
# :password => "secret",
|
12
|
+
# :region => "us"
|
13
|
+
#
|
14
|
+
def initialize(params={})
|
15
|
+
params.each_pair { |key, value| self.send("#{key}=", value) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def username=(username)
|
19
|
+
self.transport.username = username
|
20
|
+
end
|
21
|
+
|
22
|
+
def password=(password)
|
23
|
+
self.transport.password = password
|
24
|
+
end
|
25
|
+
|
26
|
+
# Sets Amazon region. Works with [ "us", "uk", "de", "ca", "fr", "jp" ].
|
27
|
+
def region=(region)
|
28
|
+
self.transport.region = region
|
29
|
+
end
|
30
|
+
|
31
|
+
# Creates an inventory batch.
|
32
|
+
#
|
33
|
+
# A sample workflow:
|
34
|
+
#
|
35
|
+
# batch = client.new_inventory_batch
|
36
|
+
# book = new_inventory_item(
|
37
|
+
# :product_id => "1234567890",
|
38
|
+
# :sku => "SKU-001",
|
39
|
+
# :price => 10.00,
|
40
|
+
# :quantity => 1)
|
41
|
+
# batch << book
|
42
|
+
# batch.upload
|
43
|
+
#
|
44
|
+
# The batch should now have an upload id assigned to it by Amazon. Once processed, you can use this to
|
45
|
+
# check the error log:
|
46
|
+
#
|
47
|
+
# report = client.new_report :upload, :id => batch.id
|
48
|
+
# report.body
|
49
|
+
#
|
50
|
+
# That should output something like the following, assuming everything went well with the upload:
|
51
|
+
#
|
52
|
+
# "Feed Processing Summary:\n\tNumber of records processed\t\t1\n\tNumber of records successful\t\t1\n\n"
|
53
|
+
#
|
54
|
+
def new_inventory_batch
|
55
|
+
Peddler::Inventory::Batch.new(self.transport.dup)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Creates an inventory item. Parameter keys are lowercased and underscored but otherwise the same as
|
59
|
+
# Amazon's colum titles in their tab-delimited templates.
|
60
|
+
def new_inventory_item(params={})
|
61
|
+
Peddler::Inventory::Item.new(params)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns count of pending inventory uploads queued at Amazon.
|
65
|
+
def inventory_queue
|
66
|
+
Peddler::Inventory::Queue.count(self.transport)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Creates an order fulfillment batch.
|
70
|
+
#
|
71
|
+
# A sample workflow:
|
72
|
+
#
|
73
|
+
# feed = client.new_order_fulfillment_feed
|
74
|
+
# fulfilled_order = new_fulfilled_order(
|
75
|
+
# :order_id => "123-1234567-1234567",
|
76
|
+
# :order_date => "2009-08-01")
|
77
|
+
# feed << fulfilled_order
|
78
|
+
# feed.upload
|
79
|
+
# feed.status
|
80
|
+
# => "_SUBMITTED_"
|
81
|
+
#
|
82
|
+
# Now, refresh the status until you see:
|
83
|
+
#
|
84
|
+
# feed.status!
|
85
|
+
# => "_DONE_"
|
86
|
+
#
|
87
|
+
# Finally, check the processing report:
|
88
|
+
#
|
89
|
+
# feed.download.to_s
|
90
|
+
#
|
91
|
+
def new_order_fulfillment_feed
|
92
|
+
Peddler::Feeds::OrderFulfillment::Batch.new(self.transport.dup)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Creates an item that can then be added to an order fulfillment feed. Keys are lowercased and underscored but
|
96
|
+
# otherwise the same as Amazon's headers. See section 7.1 in the API docs.
|
97
|
+
def new_fulfilled_order(params={})
|
98
|
+
Peddler::Feeds::OrderFulfillment::Item.new(params)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Creates an order cancellation batch.
|
102
|
+
#
|
103
|
+
# A sample workflow:
|
104
|
+
#
|
105
|
+
# feed = client.new_order_cancellation_feed
|
106
|
+
# cancelled_order = new_cancelled_order(
|
107
|
+
# :order_id => "123-1234567-1234567")
|
108
|
+
# feed << cancelled_order
|
109
|
+
# feed.upload
|
110
|
+
# feed.status
|
111
|
+
# => "_SUBMITTED_"
|
112
|
+
#
|
113
|
+
# Now, refresh the status until you see:
|
114
|
+
#
|
115
|
+
# feed.status!
|
116
|
+
# => "_DONE_"
|
117
|
+
#
|
118
|
+
# Finally, check the processing report:
|
119
|
+
#
|
120
|
+
# feed.download.to_s
|
121
|
+
#
|
122
|
+
def new_order_cancellation_feed
|
123
|
+
Peddler::Feeds::OrderCancellation::Batch.new(self.transport.dup)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Creates an item that can then be added to an order cancellation feed. Keys are lowercased and underscored but
|
127
|
+
# otherwise the same as Amazon's headers. See section 7.4 in the API docs.
|
128
|
+
def new_cancelled_order(params={})
|
129
|
+
Peddler::Feeds::OrderCancellation::Item.new(params)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Creates a refund batch.
|
133
|
+
#
|
134
|
+
# batch = client.new_refund_batch
|
135
|
+
# refund = client.new_refund(
|
136
|
+
# :order_id => "123-1234567-1234567",
|
137
|
+
# :payments_transaction_id => "12341234567890",
|
138
|
+
# :refund_amount => 10.00,
|
139
|
+
# :reason => "CouldNotShip",
|
140
|
+
# :message => "With our apologies.")
|
141
|
+
# batch << refund
|
142
|
+
# batch.upload
|
143
|
+
#
|
144
|
+
# To follow up on the status of the upload a little while afterwards:
|
145
|
+
#
|
146
|
+
# status = client.latest_reports :batch_refund, :count => 1
|
147
|
+
# report = client.new_report(
|
148
|
+
# :batch_refund,
|
149
|
+
# :id => status[0].id)
|
150
|
+
#
|
151
|
+
# Assuming the refund was successfully processed, report.body should now output:
|
152
|
+
#
|
153
|
+
# "123-1234567-1234567order-item-id: 12341234567890\tSUCCESS 10.00 is Refunded.\r\n"
|
154
|
+
#
|
155
|
+
def new_refund_batch
|
156
|
+
Peddler::Refunds::Batch.new(self.transport.dup)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Creates a refund item that can then be added to a refund batch.
|
160
|
+
#
|
161
|
+
# Reasons can be [ "GeneralAdjustment" "CouldNotShip" "DifferentItem" "MerchandiseNotReceived" "MerchandiseNotAsDescribed" ].
|
162
|
+
def new_refund(params={})
|
163
|
+
Peddler::Refunds::Item.new(params)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Creates an instance for an already-generated report. Works only with what I call legacy reports, that is,
|
167
|
+
# anything that comes before section 7 in the API docs. Report names can be [ :upload, :order, :preorder, :batch_refund, :open_listings, :open_listings_lite, :open_listings_liter ].
|
168
|
+
#
|
169
|
+
# You can download a specific report by using its ID. Otherwise, the instance will fetch the latest available report. One
|
170
|
+
# oddball exception: upload reports do require an ID and will return nil if you don't provide one.
|
171
|
+
#
|
172
|
+
# orders_report = client.new_report :order
|
173
|
+
# orders = Peddler::Handlers::TabDelimitedHandler.decode_response(orders_report.body)
|
174
|
+
# orders[0].buyer_name
|
175
|
+
# => "John Doe"
|
176
|
+
#
|
177
|
+
# preorders_report = client.new_report(
|
178
|
+
# :preorder,
|
179
|
+
# :product_line => "Books",
|
180
|
+
# :frequency => 2)
|
181
|
+
# preorders = Peddler::Handlers::TabDelimitedHandler.decode_response(preorders_report.body)
|
182
|
+
# preorders[0].average_asking_price
|
183
|
+
# => "100"
|
184
|
+
#
|
185
|
+
def new_report(name,params={})
|
186
|
+
Peddler::LegacyReports::Report.new(self.transport.dup, name, params)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Requests a report. Returns true when successful. Name can be [ :order, :open_listings, :open_listings_lite, :open_listings_liter ].
|
190
|
+
#
|
191
|
+
# Here's some sample usage:
|
192
|
+
#
|
193
|
+
# client.generate_report :order, :number_of_days => 15
|
194
|
+
#
|
195
|
+
# client.generate_report :open_listings
|
196
|
+
#
|
197
|
+
# A word of caution. Open listings may crap up with larger inventories. I will have to migrate to a cURL-based
|
198
|
+
# HTTP client to get that working again.
|
199
|
+
def generate_report(name,params={})
|
200
|
+
Peddler::LegacyReports.generate(self.transport, name, params)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Creates an unshipped order report. Takes on some optional parameters, such as :id, :starts_at, :ends_at. By default,
|
204
|
+
# it will request a new unshipped order report for the past seven days.
|
205
|
+
#
|
206
|
+
# report = client.new_unshipped_order_report
|
207
|
+
# report.status
|
208
|
+
# => "_SUBMITTED_"
|
209
|
+
#
|
210
|
+
# Now, refresh the status until you see:
|
211
|
+
#
|
212
|
+
# report.status!
|
213
|
+
# => "_DONE_"
|
214
|
+
#
|
215
|
+
# Once done, you'll get a nifty array of unshipped orders:
|
216
|
+
#
|
217
|
+
# report.unshipped_orders
|
218
|
+
#
|
219
|
+
def new_unshipped_orders_report(params={})
|
220
|
+
Peddler::Reports::UnshippedOrdersReport.new(self.transport.dup, params)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Returns status of most recent reports. Optional "count" defaults to 10. Name can be [ :upload, :order, :batch_refund, :open_listings, :open_listings_lite, :open_listings_liter ].
|
224
|
+
#
|
225
|
+
# Some sample usage:
|
226
|
+
#
|
227
|
+
# reports = client.latest_reports :order, :count => 1
|
228
|
+
# reports[0]
|
229
|
+
# => #<Peddler::LegacyReports::ReportStatus starts_at="07-29-2009:10-00-06" ...
|
230
|
+
#
|
231
|
+
def latest_reports(name,params={})
|
232
|
+
Peddler::LegacyReports.latest(self.transport, name, params)
|
233
|
+
end
|
234
|
+
|
235
|
+
protected
|
236
|
+
def transport #:nodoc:all
|
237
|
+
@transport ||= Peddler::Transport.new
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module Peddler
|
2
|
+
# This module includes functionality to handle the charge-when-ship-related feeds Amazon added to the API
|
3
|
+
# in its latest incarnation in 2009.
|
4
|
+
module Feeds
|
5
|
+
# Downloadable file. The processing report in case of feeds. Outputs Amazon's response verbatim.
|
6
|
+
# Will add functionality to parse the response some time down the road.
|
7
|
+
class Download
|
8
|
+
attr_accessor :id, :type, :related_reference_id, :available_at, :acknowledged
|
9
|
+
|
10
|
+
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
|
+
@transport = transport
|
18
|
+
params.each_pair{ |key, value| self.send "#{@mapped_params[key]}=", value }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Retrieves and returns report
|
22
|
+
def to_s
|
23
|
+
@body ||= download_report
|
24
|
+
end
|
25
|
+
private
|
26
|
+
def download_report
|
27
|
+
return nil if @id.nil?
|
28
|
+
@transport.modernize_request
|
29
|
+
@transport.query_params.merge!({
|
30
|
+
"Action" => "download",
|
31
|
+
"downloadId" => @id})
|
32
|
+
@transport.execute_request
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# This is the base class.
|
37
|
+
class Feed
|
38
|
+
attr_writer :file_content
|
39
|
+
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
|
+
|
41
|
+
def initialize(transport)
|
42
|
+
@transport = transport
|
43
|
+
@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
|
+
end
|
57
|
+
|
58
|
+
# Returns content of the upload file.
|
59
|
+
def file_content
|
60
|
+
return @file_content if @file_content
|
61
|
+
out = @file_header
|
62
|
+
@batch.each{ |item| out << item.to_s }
|
63
|
+
@file_content = out
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns status and will also refresh if not already "done."
|
67
|
+
def status!
|
68
|
+
return @status if @status.nil? || @status =~ /_DONE_/
|
69
|
+
refresh_status
|
70
|
+
@status
|
71
|
+
end
|
72
|
+
|
73
|
+
# Uploads batch.
|
74
|
+
def upload
|
75
|
+
raise PeddlerError.new("Batch already uploaded") unless @id.nil?
|
76
|
+
@transport.modernize_request
|
77
|
+
@transport.query_params.merge!({
|
78
|
+
"Action" => "upload",
|
79
|
+
"uploadType" => @type})
|
80
|
+
@transport.body = file_content
|
81
|
+
res = @transport.execute_request
|
82
|
+
process_response(res)
|
83
|
+
@status
|
84
|
+
end
|
85
|
+
|
86
|
+
# Adds an item to the batch.
|
87
|
+
def <<(item)
|
88
|
+
@batch << item
|
89
|
+
end
|
90
|
+
private
|
91
|
+
def refresh_status
|
92
|
+
@transport.modernize_request
|
93
|
+
@transport.query_params.merge!({
|
94
|
+
"Action" => "uploadStatus",
|
95
|
+
"uploadId" => @id})
|
96
|
+
res = @transport.execute_request
|
97
|
+
process_response(res)
|
98
|
+
end
|
99
|
+
|
100
|
+
def process_response(res)
|
101
|
+
xml = Peddler::Handlers::XMLHandler.decode_response(res)
|
102
|
+
params = Peddler::Handlers::XMLHandler.parse(:upload, xml)
|
103
|
+
if params[0]
|
104
|
+
params[0].each_pair do |key, value|
|
105
|
+
if key == "RelatedDownloadsList"
|
106
|
+
params = Peddler::Handlers::XMLHandler.parse(:download, value)
|
107
|
+
@download = Peddler::Feeds::Download.new(@transport, params[0])
|
108
|
+
else
|
109
|
+
self.send "#{@mapped_params[key]}=", value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
module OrderFulfillment
|
117
|
+
# This class contains methods to upload order fulfillment info to Amazon.
|
118
|
+
# See sections 7.1 through 7.3 in the API documentation for more detail.
|
119
|
+
class Batch < Peddler::Feeds::Feed
|
120
|
+
def initialize(transport)
|
121
|
+
@file_header = "order-id\torder-item-id\tquantity\tship-date\tcarrier-code\tcarrier-name\ttracking-number\tship-method\r\n"
|
122
|
+
@type = "_POST_FLAT_FILE_FULFILLMENT_DATA_"
|
123
|
+
super(transport)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# This is an order fulfillment item.
|
128
|
+
class Item
|
129
|
+
attr_accessor :order_id, :order_item_id, :quantity, :ship_date, :carrier_name, :tracking_number, :ship_method
|
130
|
+
attr_reader :carrier_code
|
131
|
+
|
132
|
+
def initialize(params={})
|
133
|
+
params.each_pair{ |key, value| send("#{key}=", value) }
|
134
|
+
end
|
135
|
+
|
136
|
+
# Validates when setting carrier code.
|
137
|
+
def carrier_code=(carrier_code)
|
138
|
+
@carrier_code = carrier_code if %w{USPS UPS FedEx other}.include?(carrier_code)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Outputs a formatted line for the tab-delimited upload file.
|
142
|
+
def to_s
|
143
|
+
"#{@order_id}\t#{@order_item_id}\t#{@quantity}\t#{@ship_date}\t#{@carrier_code}\t#{@carrier_name}\t#{@tracking_number}\t#{@ship_method}\r\n"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# This module contains methods to upload cancelled orders to Amazon.
|
149
|
+
# See section 7.4 in the API documentation for more detail.
|
150
|
+
module OrderCancellation
|
151
|
+
class Batch < Peddler::Feeds::Feed
|
152
|
+
def initialize(transport)
|
153
|
+
@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
|
+
"order-id\tcancellation-reason-code\tamazon-order-item-code\r\n"
|
155
|
+
@type = "_POST_FLAT_FILE_ORDER_ACKNOWLEDGEMENT_DATA_"
|
156
|
+
super(transport)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# This is a cancelled order item.
|
161
|
+
class Item
|
162
|
+
attr_accessor :order_id, :amazon_order_item_code
|
163
|
+
attr_reader :cancellation_reason_code
|
164
|
+
|
165
|
+
def initialize(params={})
|
166
|
+
params.each_pair{ |key, value| send("#{key}=", value) }
|
167
|
+
end
|
168
|
+
|
169
|
+
# Validates when setting cancellation reason code.
|
170
|
+
def cancellation_reason_code=(cancellation_reason_code)
|
171
|
+
@cancellation_reason_code = cancellation_reason_code if %w{ BuyerCanceled CustomerExchange CustomerReturn GeneralAdjustment MerchandiseNotReceived NoInventory ShippingAddressUndeliverable }.include?(cancellation_reason_code)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Outputs a formatted line for the tab-delimited upload file.
|
175
|
+
def to_s
|
176
|
+
"#{@order_id}\t#{@cancellation_reason_code}\t#{@amazon_order_item_code}\r\n"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|