shopify_api 4.10.0 → 4.11.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.
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