shopify_api 4.10.0 → 4.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 337b8ab5bf4f4e4fad2128ae8904e5eb796b82be
4
- data.tar.gz: 86c8ea358c70f9613a46cd036a5dbc5d7eee1706
3
+ metadata.gz: b0cc884464a1fe2083dd24a14965d0480f67e292
4
+ data.tar.gz: 5a29ecedb51e1ba5c02fbde2c341f9bedef57b9e
5
5
  SHA512:
6
- metadata.gz: 6021f43b4b1837e770fca8e94fc106b04e88c38ad686a322c9d4d75718ec99e0894c96265286ce4d5fe9b6789c10b57ab4aeae025923a070cb3e51d1d2de7fa8
7
- data.tar.gz: 36a8eab6d23df41071c8a496de1cc7b7f198f4cb7d459eb9d3e27d4fde4ac43e9aad1ac1763dc9768a9dae9c13eb6fd304403f1563f8bc30f769d6a979863394
6
+ metadata.gz: 99151c8edf235fb8b76c90acb943304f330cab627490b5829d968b4c6a35427d51aa4b982adb890a5a061cfe94a5f6a257ae5863189ee056499017a533d8fb90
7
+ data.tar.gz: eb2b22d6ff86b6d97b69cc254029ac4bb1dc680ba88ac74f55bab22d2e2809a4a8f3a6efe5d85b14ca16f729beb060af34a64508bec638b9c20c4b46dd17cac8
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ == Version 4.11.0
2
+
3
+ * Added `ShopifyAPI::InventoryItem`
4
+ * Added `ShopifyAPI::InventoryLevel`
5
+ * Added `#inventory_levels` method to `ShopifyAPI::Location`
6
+
1
7
  == Version 4.10.0
2
8
 
3
9
  * Added `ShopifyAPI::AccessScope`
@@ -42,7 +42,7 @@ module ShopifyAPI
42
42
  prefix_options, query_options = split_options(prefix_options) if query_options.nil?
43
43
  "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
44
44
  end
45
-
45
+
46
46
  # find an asset by key:
47
47
  # ShopifyAPI::Asset.find('layout/theme.liquid', :params => {:theme_id => 99})
48
48
  def self.find(*args)
@@ -57,7 +57,7 @@ module ShopifyAPI
57
57
  resource
58
58
  end
59
59
  end
60
-
60
+
61
61
  # For text assets, Shopify returns the data in the 'value' attribute.
62
62
  # For binary assets, the data is base-64-encoded and returned in the
63
63
  # 'attachment' attribute. This accessor returns the data in both cases.
@@ -65,28 +65,28 @@ module ShopifyAPI
65
65
  attributes['value'] ||
66
66
  (attributes['attachment'] ? Base64.decode64(attributes['attachment']) : nil)
67
67
  end
68
-
68
+
69
69
  def attach(data)
70
70
  self.attachment = Base64.encode64(data)
71
71
  end
72
-
72
+
73
73
  def destroy
74
74
  connection.delete(element_path(prefix_options.merge(:asset => {:key => key})), self.class.headers)
75
75
  end
76
-
76
+
77
77
  def new?
78
78
  false
79
79
  end
80
-
80
+
81
81
  def method_missing(method_symbol, *arguments) #:nodoc:
82
82
  if %w{value= attachment= src= source_key=}.include?(method_symbol)
83
83
  wipe_value_attributes
84
84
  end
85
85
  super
86
86
  end
87
-
87
+
88
88
  private
89
-
89
+
90
90
  def wipe_value_attributes
91
91
  %w{value attachment src source_key}.each do |attr|
92
92
  attributes.delete(attr)
@@ -1,4 +1,4 @@
1
1
  module ShopifyAPI
2
2
  class BillingAddress < Base
3
- end
3
+ end
4
4
  end
@@ -6,14 +6,14 @@ module ShopifyAPI
6
6
  def products
7
7
  Product.find(:all, :params => {:collection_id => self.id})
8
8
  end
9
-
9
+
10
10
  def add_product(product)
11
11
  Collect.create(:collection_id => self.id, :product_id => product.id)
12
12
  end
13
-
13
+
14
14
  def remove_product(product)
15
15
  collect = Collect.find(:first, :params => {:collection_id => self.id, :product_id => product.id})
16
16
  collect.destroy if collect
17
17
  end
18
- end
18
+ end
19
19
  end
@@ -1,13 +1,13 @@
1
1
  module ShopifyAPI
2
2
  class Image < Base
3
3
  init_prefix :product
4
-
4
+
5
5
  # generate a method for each possible image variant
6
6
  [:pico, :icon, :thumb, :small, :compact, :medium, :large, :grande, :original].each do |m|
7
7
  reg_exp_match = "/\\1_#{m}.\\2"
8
8
  define_method(m) { src.gsub(/\/(.*)\.(\w{2,4})/, reg_exp_match) }
9
9
  end
10
-
10
+
11
11
  def attach_image(data, filename = nil)
12
12
  attributes['attachment'] = Base64.encode64(data)
13
13
  attributes['filename'] = filename unless filename.nil?
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyAPI
4
+ class InventoryItem < Base
5
+ end
6
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyAPI
4
+ class InventoryLevel < Base
5
+
6
+ # The default path structure in ActiveResource for delete would result in:
7
+ # /admin/inventory_levels/#{ inventory_level.id }.json?#{ params }, but since
8
+ # InventroyLevels are a second class resource made up of a Where and a What
9
+ # (Location and InventoryItem), it does not have a resource ID. Here we
10
+ # redefine element_path to remove the id so HTTP DELETE requests go to
11
+ # /admin/inventory_levels.json?#{ params } instead.
12
+ #
13
+ def self.element_path(prefix_options = {}, query_options = nil)
14
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
15
+ "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
16
+ end
17
+
18
+ def destroy
19
+ load_attributes_from_response(
20
+ self.class.delete('/', location_id: location_id, inventory_item_id: inventory_item_id)
21
+ )
22
+ end
23
+
24
+ def connect(relocate_if_necessary: nil)
25
+ body = { location_id: location_id, inventory_item_id: inventory_item_id }
26
+ body[:relocate_if_necessary] = relocate_if_necessary unless relocate_if_necessary.nil?
27
+ load_attributes_from_response(
28
+ self.class.post(:connect, {}, body.to_json)
29
+ )
30
+ end
31
+
32
+ def set(new_available, disconnect_if_necessary: nil)
33
+ body = {
34
+ location_id: location_id,
35
+ inventory_item_id: inventory_item_id,
36
+ available: new_available
37
+ }
38
+ body[:disconnect_if_necessary] = disconnect_if_necessary unless disconnect_if_necessary.nil?
39
+ load_attributes_from_response(
40
+ self.class.post(:set, {}, body.to_json)
41
+ )
42
+ end
43
+
44
+ def adjust(available_adjustment)
45
+ body = {
46
+ location_id: location_id,
47
+ inventory_item_id: inventory_item_id,
48
+ available_adjustment: available_adjustment
49
+ }
50
+ load_attributes_from_response(
51
+ self.class.post(:adjust, {}, body.to_json)
52
+ )
53
+ end
54
+ end
55
+ end
@@ -1,4 +1,8 @@
1
1
  module ShopifyAPI
2
2
  class Location < Base
3
+
4
+ def inventory_levels
5
+ ShopifyAPI::InventoryLevel.find(:all, from: "/admin/locations/#{id}/inventory_levels.json")
6
+ end
3
7
  end
4
8
  end
@@ -3,8 +3,13 @@ module ShopifyAPI
3
3
  include Events
4
4
  include Metafields
5
5
 
6
- def close; load_attributes_from_response(post(:close, {}, only_id)); end
7
- def open; load_attributes_from_response(post(:open, {}, only_id)); end
6
+ def close
7
+ load_attributes_from_response(post(:close, {}, only_id))
8
+ end
9
+
10
+ def open
11
+ load_attributes_from_response(post(:open, {}, only_id))
12
+ end
8
13
 
9
14
  def cancel(options = {})
10
15
  load_attributes_from_response(post(:cancel, {}, options.to_json))
@@ -13,19 +13,19 @@ module ShopifyAPI
13
13
  format % prices.min
14
14
  end
15
15
  end
16
-
16
+
17
17
  def collections
18
18
  CustomCollection.find(:all, :params => {:product_id => self.id})
19
19
  end
20
-
20
+
21
21
  def smart_collections
22
22
  SmartCollection.find(:all, :params => {:product_id => self.id})
23
23
  end
24
-
24
+
25
25
  def add_to_collection(collection)
26
26
  collection.add_product(self)
27
27
  end
28
-
28
+
29
29
  def remove_from_collection(collection)
30
30
  collection.remove_product(self)
31
31
  end
@@ -1,4 +1,4 @@
1
1
  module ShopifyAPI
2
2
  class ShippingLine < Base
3
- end
3
+ end
4
4
  end
@@ -1,5 +1,5 @@
1
1
  module ShopifyAPI
2
- # Shop object. Use Shop.current to receive
2
+ # Shop object. Use Shop.current to receive
3
3
  # the shop.
4
4
  class Shop < Base
5
5
  def self.current(options={})
@@ -11,13 +11,13 @@ module ShopifyAPI
11
11
  end
12
12
 
13
13
  def add_metafield(metafield)
14
- raise ArgumentError, "You can only add metafields to resource that has been saved" if new?
14
+ raise ArgumentError, "You can only add metafields to resource that has been saved" if new?
15
15
  metafield.save
16
16
  metafield
17
17
  end
18
-
18
+
19
19
  def events
20
20
  Event.find(:all)
21
21
  end
22
- end
22
+ end
23
23
  end
@@ -1,3 +1,3 @@
1
1
  module ShopifyAPI
2
- VERSION = "4.10.0"
2
+ VERSION = "4.11.0"
3
3
  end
@@ -0,0 +1,7 @@
1
+ {
2
+ "inventory_level" : {
3
+ "inventory_item_id": 808950810,
4
+ "location_id": 905684977,
5
+ "available": 1
6
+ }
7
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "inventory_levels": [
3
+ {
4
+ "inventory_item_id": 39072856,
5
+ "location_id": 487838322,
6
+ "available": 27
7
+ },
8
+ {
9
+ "inventory_item_id": 808950810,
10
+ "location_id": 905684977,
11
+ "available": 1
12
+ },
13
+ {
14
+ "inventory_item_id": 808950810,
15
+ "location_id": 487838322,
16
+ "available": 9
17
+ },
18
+ {
19
+ "inventory_item_id": 39072856,
20
+ "location_id": 905684977,
21
+ "available": 3
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+
3
+ class InventoryLevelTest < Test::Unit::TestCase
4
+ def setup
5
+ super
6
+ @inventory_level_response = ActiveSupport::JSON.decode load_fixture('inventory_level')
7
+ @inventory_level = ShopifyAPI::InventoryLevel.new(@inventory_level_response['inventory_level'])
8
+ end
9
+
10
+ test ".find with inventory_item_ids and location_ids returns expected inventory levels" do
11
+ params = { inventory_item_ids: [808950810, 39072856], location_ids: [905684977, 487838322] }
12
+ fake "inventory_levels.json?#{params.to_param}", extension: false, method: :get,
13
+ status: 200, body: load_fixture('inventory_levels')
14
+ inventory_levels = ShopifyAPI::InventoryLevel.find(:all, params: params)
15
+
16
+ assert inventory_levels.all? { |item|
17
+ params[:location_ids].include?(item.location_id) &&
18
+ params[:inventory_item_ids].include?(item.inventory_item_id)
19
+ }, message: 'Response contained inventory_items or locations not requested.'
20
+ end
21
+
22
+ test '#adjust with adjustment value returns inventory_level with available increased by adjustment value' do
23
+ adjustment = 5
24
+ updated_available = @inventory_level.available + adjustment
25
+ @inventory_level_response[:available] = updated_available
26
+
27
+ fake 'inventory_levels/adjust', method: :post, body: ActiveSupport::JSON.encode(@inventory_level_response)
28
+ @inventory_level.adjust(adjustment)
29
+ assert_equal updated_available, @inventory_level.available
30
+ end
31
+
32
+ test '#connect saves an inventory_level associated with inventory_item and location_id' do
33
+ params = { inventory_item_id: 808950810, location_id: 99999999 }
34
+ response = params.clone
35
+ response[:available] = 0
36
+
37
+ fake 'inventory_levels/connect', method: :post, body: ActiveSupport::JSON.encode(response)
38
+ inventory_level = ShopifyAPI::InventoryLevel.new(params)
39
+ inventory_level.connect
40
+ assert_equal 0, inventory_level.available, message: 'expected newly connected location to have 0 inventory'
41
+ end
42
+
43
+ test '#destroy removes inventory_level and returns nil' do
44
+ params = { inventory_item_id: @inventory_level.inventory_item_id, location_id: @inventory_level.location_id }
45
+ fake "inventory_levels.json?#{params.to_param}", extension: false, method: :delete, status: 204, body: nil
46
+ assert_nil @inventory_level.destroy
47
+ end
48
+
49
+ test '#set with available value returns inventory_level with available as the available value' do
50
+ available = 13
51
+ response = @inventory_level_response.clone
52
+ response['inventory_level']['available'] = available
53
+
54
+ fake 'inventory_levels/set', method: :post, body: ActiveSupport::JSON.encode(response)
55
+ @inventory_level.set(available)
56
+
57
+ assert_equal available, @inventory_level.available
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class LocationTest < Test::Unit::TestCase
4
+ test '#inventory_levels returns all inventory_levels associated with this location' do
5
+ location = ShopifyAPI::Location.new(id: 487838322)
6
+ expected_body = JSON.parse(load_fixture('inventory_levels'))
7
+ expected_body['inventory_levels'].delete_if {|level| level['location_id'] != location.id }
8
+ fake "locations/#{location.id}/inventory_levels", method: :get, status: 200, body: JSON(expected_body).to_s
9
+ inventory_levels = location.inventory_levels
10
+
11
+ assert inventory_levels.all? { |item| item.location_id == location.id },
12
+ message: 'Response contained locations other than the current location.'
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.10.0
4
+ version: 4.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-23 00:00:00.000000000 Z
11
+ date: 2018-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -184,6 +184,8 @@ files:
184
184
  - lib/shopify_api/resources/fulfillment_service.rb
185
185
  - lib/shopify_api/resources/gift_card.rb
186
186
  - lib/shopify_api/resources/image.rb
187
+ - lib/shopify_api/resources/inventory_item.rb
188
+ - lib/shopify_api/resources/inventory_level.rb
187
189
  - lib/shopify_api/resources/line_item.rb
188
190
  - lib/shopify_api/resources/location.rb
189
191
  - lib/shopify_api/resources/marketing_event.rb
@@ -288,6 +290,8 @@ files:
288
290
  - test/fixtures/gift_card_disabled.json
289
291
  - test/fixtures/image.json
290
292
  - test/fixtures/images.json
293
+ - test/fixtures/inventory_level.json
294
+ - test/fixtures/inventory_levels.json
291
295
  - test/fixtures/marketing_event.json
292
296
  - test/fixtures/marketing_events.json
293
297
  - test/fixtures/metafield.json
@@ -336,7 +340,9 @@ files:
336
340
  - test/fulfillment_test.rb
337
341
  - test/gift_card_test.rb
338
342
  - test/image_test.rb
343
+ - test/inventory_level_test.rb
339
344
  - test/limits_test.rb
345
+ - test/location_test.rb
340
346
  - test/marketing_event_test.rb
341
347
  - test/metafield_test.rb
342
348
  - test/o_auth_test.rb