Jon Grenning 7 anni fa
parent
commit
e9419be877

+ 6 - 0
lib/shopify_api/resources/inventory_item.rb

@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+module ShopifyAPI
+  class InventoryItem < Base
+  end
+end

+ 56 - 0
lib/shopify_api/resources/inventory_level.rb

@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module ShopifyAPI
+  class InventoryLevel < Base
+
+    # The default path structure in ActiveResource for delete would result in:
+    # /admin/inventory_levels/#{ inventory_level.id }.json?#{ params }, but since
+    # InventroyLevels are a second class resource made up of a Where and a What
+    # (Location and InventoryItem), it does not have a resource ID. Here we
+    # redefine element_path to remove the id so HTTP DELETE requests go to
+    # /admin/inventory_levels.json?#{ params } instead.
+    #
+    def self.element_path(prefix_options = {}, query_options = nil)
+      prefix_options, query_options = split_options(prefix_options) if query_options.nil?
+      "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
+    end
+
+    def destroy
+      load_attributes_from_response(
+        self.class.delete('/', location_id: location_id,
+                               inventory_item_id: inventory_item_id)
+      )
+    end
+
+    def connect(relocate_if_necessary: nil)
+      body = { location_id: location_id, inventory_item_id: inventory_item_id }
+      body[:relocate_if_necessary] = relocate_if_necessary unless relocate_if_necessary.nil?
+      load_attributes_from_response(
+        self.class.post(:connect, {}, body.to_json)
+      )
+    end
+
+    def set(new_available, disconnect_if_necessary: nil)
+      body = {
+        location_id: location_id,
+        inventory_item_id: inventory_item_id,
+        available: new_available
+      }
+      body[:disconnect_if_necessary] = disconnect_if_necessary unless disconnect_if_necessary.nil?
+      load_attributes_from_response(
+        self.class.post(:set, {}, body.to_json)
+      )
+    end
+
+    def adjust(available_adjustment)
+      body = {
+        location_id: location_id,
+        inventory_item_id: inventory_item_id,
+        available_adjustment: available_adjustment
+      }
+      load_attributes_from_response(
+        self.class.post(:adjust, {}, body.to_json)
+      )
+    end
+  end
+end

+ 7 - 0
test/fixtures/inventory_level.json

@@ -0,0 +1,7 @@
+{
+  "inventory_level" : {
+      "inventory_item_id": 808950810,
+      "location_id": 905684977,
+      "available": 1
+  }
+}

+ 24 - 0
test/fixtures/inventory_levels.json

@@ -0,0 +1,24 @@
+{
+  "inventory_levels": [
+    {
+      "inventory_item_id": 39072856,
+      "location_id": 487838322,
+      "available": 27
+    },
+    {
+      "inventory_item_id": 808950810,
+      "location_id": 905684977,
+      "available": 1
+    },
+    {
+      "inventory_item_id": 808950810,
+      "location_id": 487838322,
+      "available": 9
+    },
+    {
+      "inventory_item_id": 39072856,
+      "location_id": 905684977,
+      "available": 3
+    }
+  ]
+}

+ 59 - 0
test/inventory_level_test.rb

@@ -0,0 +1,59 @@
+require 'test_helper'
+
+class InventoryLevelTest < Test::Unit::TestCase
+  def setup
+    super
+    @inventory_level_response = ActiveSupport::JSON.decode load_fixture('inventory_level')
+    @inventory_level = ShopifyAPI::InventoryLevel.new(@inventory_level_response['inventory_level'])
+  end
+
+  test 'Retrieve inventory levels for the specified inventory_items and locations' do
+    params = { inventory_item_ids: [808950810, 39072856], location_ids: [905684977, 487838322] }
+    fake "inventory_levels.json?#{params.to_param}", extension: false, method: :get,
+          status: 200, body: load_fixture('inventory_levels')
+    inventory_levels = ShopifyAPI::InventoryLevel.find(:all, params: params)
+
+    assert inventory_levels.all? { |item|
+      params[:location_ids].include?(item.location_id) &&
+      params[:inventory_item_ids].include?(item.inventory_item_id)
+    }, message: 'Response contained inventory_items or locations not requested.'
+  end
+
+  test 'Adjust an inventory level by 5' do
+    adjustment = 5
+    updated_available = @inventory_level.available + adjustment
+    @inventory_level_response[:available] = updated_available
+
+    fake 'inventory_levels/adjust', method: :post, body: ActiveSupport::JSON.encode(@inventory_level_response)
+    @inventory_level.adjust(adjustment)
+    assert_equal updated_available, @inventory_level.available
+  end
+
+  test 'Connect an inventory_item to a location' do
+    params = { inventory_item_id: 808950810, location_id: 99999999 }
+    response = params.clone
+    response[:available] = 0
+
+    fake 'inventory_levels/connect', method: :post, body: ActiveSupport::JSON.encode(response)
+    inventory_level = ShopifyAPI::InventoryLevel.new(params)
+    inventory_level.connect
+    assert_equal 0, inventory_level.available, message: 'expected newly connected location to have 0 inventory'
+  end
+
+  test 'Destroy an inventory_level' do
+    params = { inventory_item_id: @inventory_level.inventory_item_id, location_id: @inventory_level.location_id }
+    fake "inventory_levels.json?#{params.to_param}", extension: false, method: :delete, status: 204, body: nil
+    assert_nil @inventory_level.destroy
+  end
+
+  test 'Set the available inventory for an inventory_level' do
+    available = 13
+    response = @inventory_level_response.clone
+    response['inventory_level']['available'] = available
+
+    fake 'inventory_levels/set', method: :post, body: ActiveSupport::JSON.encode(response)
+    @inventory_level.set(available)
+
+    assert_equal available, @inventory_level.available
+  end
+end