elyngved / ruby-mws

A Ruby library that wraps the Amazon MWS API.
MIT License
41 stars 64 forks source link

Add support for Inventory Feed API (via new Inventory#update_inventory_supply method) #4

Open alexdowad opened 12 years ago

alexdowad commented 12 years ago

(Development of this patch was funded by Sam Hamilton of Mad Jungle. It was done for Sam's web site, but he gave me permission to donate the code back to ruby-mws so others can benefit from it. Thanks, Sam!)

This PR adds support for the Inventory Feeds API, so users of ruby-mws can update the inventory stock levels for their Amazon MWS products.

Using the Feeds API is a bit different from the other APIs. Most of the others just require a single HTTP request, but the Feeds API requires a series of related requests; first to submit a "feed" or XML document, then to check whether Amazon is finished processing the "feed", then to check whether Amazon encountered any errors while processing the "feed".

This means that the code for the new method is rather long compared to the other existing ones. If support for more of the Feeds APIs was desired, a lot of this code could be factored out into a common method. But for now, this is the first one.

The Feeds API requires a "Content-MD5" header be used on the HTTP POST request, so I added some code to MWS::API::Base which can compute and add the needed header. I think it might be useful for access to more of the Amazon MWS API in the future.

elyngved commented 11 years ago

Hl @alexdowad, thanks for this PR. I'm finally picking this project back up. Have you been using it with success?

alexdowad commented 11 years ago

The project for which I wrote this patch was successfully completed a long time ago, and the customer hasn't come back with any complaints. So I assume that ruby-mws is working for them. (Thanks!)

elyngved commented 11 years ago

Good to hear. Do you have any specs to contribute as well? Or at least examples of usage? Thanks

alexdowad commented 11 years ago

Hi! The project which I wrote this patch for is already finished, and I'm currently busy working on other projects, so I don't have time to write up specs for this code. I can show you an example of usage (from a Rake task), though:

require 'ruby-mws'

desc "Upload current stock levels to Amazon MWS"
task :update_amazon_stock => :environment do
  # get a list of all the products which may need to be updated on Amazon
  products = Spree::Product.find(:all, :include => :master)
  skus     = {}
  products.each do |product|
    skus[product.sku] = product.count_on_hand
  end

  # connect to Amazon MWS API
  mws = MWS.new(:aws_access_key_id => 'omitted',
                :secret_access_key => 'omitted',
                :seller_id => 'omitted',
                :marketplace_id => 'omitted',
                :host => 'mws.amazonservices.co.uk')

  # check what stock levels they have in their DB right now
  puts "Retrieving inventory levels from Amazon MWS..."
  response = mws.inventory.list_inventory_supply(:seller_skus => skus.keys)
  stock    = [*response.inventory_supply_list]

  # build up a list of SKUs for products which need updating
  to_update = {}
  stock.each do |item|
    if !skus.key?(item.seller_sku)
      puts "SKU #{item.seller_sku} is up on Amazon MWS, but we don't have it in our Spree database!"
    elsif item.in_stock_supply_quantity.to_i != skus[item.seller_sku]
      puts "Need to update quantity of #{item.seller_sku} from #{item.in_stock_supply_quantity} to #{skus[item.seller_sku]}"
      to_update[item.seller_sku] = skus[item.seller_sku]
    end
  end

  # send an XML document to Amazon updating all outdated inventory data
  puts "Sending XML document to Amazon..."
  if mws.inventory.update_inventory_supply('omitted', to_update)
    puts "Updated successfully!"
  end
end
phstc commented 11 years ago

No news for this PR?

SunnyIzr commented 11 years ago

Hey Guys--yea just wondering if this PR was to be merged. Let me know--this would be SUPER helpful!

elyngved commented 11 years ago

Hey all, sorry I've been so busy and disregarding this project. I'm going to take a look at this over the next few days. I haven't had a chance to use the inventory API but I will be soon so I'll have use for this method and I'll be building support for other inventory API endpoints in the near future. Thanks for your patience.