spree_api 4.8.3 → 4.9.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 +4 -4
- data/app/controllers/concerns/spree/api/v2/caching.rb +14 -8
- data/app/controllers/concerns/spree/api/v2/storefront/order_concern.rb +2 -2
- data/app/controllers/spree/api/v2/base_controller.rb +7 -1
- data/app/controllers/spree/api/v2/storefront/products_controller.rb +8 -1
- data/app/controllers/spree/api/v2/storefront/variants_controller.rb +41 -0
- data/app/controllers/spree/api/v2/storefront/wishlists_controller.rb +43 -0
- data/app/models/concerns/spree/webhooks/has_webhooks.rb +13 -5
- data/app/models/spree/oauth_application.rb +7 -0
- data/app/models/spree/order/webhooks.rb +39 -0
- data/app/models/spree/payment/webhooks.rb +23 -0
- data/app/models/spree/product/webhooks.rb +42 -0
- data/app/models/spree/shipment/webhooks.rb +19 -0
- data/app/models/spree/stock_item/webhooks.rb +40 -0
- data/app/models/spree/stock_movement/webhooks.rb +49 -0
- data/app/models/spree/variant/webhooks.rb +25 -0
- data/app/models/spree/webhooks/subscriber.rb +4 -0
- data/app/serializers/spree/api/v2/platform/admin_user_serializer.rb +11 -0
- data/app/serializers/spree/api/v2/platform/refund_serializer.rb +1 -0
- data/app/serializers/spree/api/v2/platform/store_credit_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/shipping_category_serializer.rb +10 -0
- data/app/serializers/spree/v2/storefront/shipping_method_serializer.rb +10 -0
- data/app/services/spree/api/error_handler.rb +1 -0
- data/app/services/spree/webhooks/subscribers/handle_request.rb +4 -4
- data/app/services/spree/webhooks/subscribers/make_request.rb +2 -2
- data/app/services/spree/webhooks/subscribers/queue_requests.rb +3 -3
- data/config/initializers/doorkeeper.rb +2 -0
- data/config/routes.rb +4 -1
- data/lib/spree/api/configuration.rb +3 -1
- data/lib/spree/api/dependencies.rb +5 -1
- data/lib/spree/api/engine.rb +0 -8
- data/lib/spree/api/testing_support/matchers/webhooks.rb +4 -4
- data/lib/spree/api/testing_support/spree_webhooks.rb +2 -2
- metadata +17 -13
- data/app/models/spree/api/webhooks/order_decorator.rb +0 -43
- data/app/models/spree/api/webhooks/payment_decorator.rb +0 -26
- data/app/models/spree/api/webhooks/product_decorator.rb +0 -46
- data/app/models/spree/api/webhooks/shipment_decorator.rb +0 -21
- data/app/models/spree/api/webhooks/stock_item_decorator.rb +0 -43
- data/app/models/spree/api/webhooks/stock_movement_decorator.rb +0 -52
- data/app/models/spree/api/webhooks/variant_decorator.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 012d9b5279e5919cc152eba9678ca8682c1baca7b9256ff22c491db95d74de5a
|
4
|
+
data.tar.gz: 56e0fdb4db5ea020e7086b91fa3c401ea76527ea0b5408ca734e9a0abf72502b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f9d2e9805651277ad363af26e8a97a10e89899336083e5b8f511d63bd99be127ab41b11c0c699fb42492c4d1f490a540273aaa6ec33ee9abcb221a36149b2e8
|
7
|
+
data.tar.gz: 8050de3c76e4d358a4d0198d87ea27e91ca2bc373ce8dfa61795207334b25e19751a7a1414bb17a3421c38037ae2ad51424e7a98506107c299f53acba8723ffa
|
@@ -5,22 +5,22 @@ module Spree
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
def collection_cache_key(collection)
|
8
|
-
|
8
|
+
# Calling reselect('*') is a workaround for the joined translations table
|
9
|
+
collection_cache_key = collection.unscope(:includes).unscope(:order).unscope(:group).reselect('*').cache_key_with_version
|
9
10
|
|
10
|
-
|
11
|
-
max_updated_at = ids_and_timestamps.map(&:last).max
|
11
|
+
params.delete(:page) if params[:page] == 1
|
12
12
|
|
13
13
|
cache_key_parts = [
|
14
|
-
|
15
|
-
max_updated_at,
|
16
|
-
ids,
|
14
|
+
collection_cache_key,
|
17
15
|
resource_includes,
|
18
16
|
sparse_fields,
|
19
|
-
|
17
|
+
serializer_params_cache_key,
|
20
18
|
params[:sort]&.strip,
|
21
19
|
params[:page]&.to_s&.strip,
|
22
20
|
params[:per_page]&.to_s&.strip,
|
23
|
-
]
|
21
|
+
]
|
22
|
+
cache_key_parts += additional_cache_key_parts if defined?(additional_cache_key_parts)
|
23
|
+
cache_key_parts = cache_key_parts.flatten.join('-')
|
24
24
|
|
25
25
|
Digest::MD5.hexdigest(cache_key_parts)
|
26
26
|
end
|
@@ -31,6 +31,12 @@ module Spree
|
|
31
31
|
expires_in: Spree::Api::Config[:api_v2_collection_cache_ttl],
|
32
32
|
}
|
33
33
|
end
|
34
|
+
|
35
|
+
def serializer_params_cache_key
|
36
|
+
serializer_params.values.map do |param|
|
37
|
+
param.try(:cache_key) || param.try(:flatten).try(:join, '-') || param.try(:to_s)
|
38
|
+
end.compact.join('-')
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
end
|
@@ -9,7 +9,7 @@ module Spree
|
|
9
9
|
if result.success?
|
10
10
|
render_serialized_payload { serialized_current_order }
|
11
11
|
else
|
12
|
-
render_error_payload(result.error)
|
12
|
+
render_error_payload(result.error&.value || result.value)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -18,7 +18,7 @@ module Spree
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def order_token
|
21
|
-
request.headers['X-Spree-Order-Token'] || params[:order_token]
|
21
|
+
request.headers['X-Vendo-Order-Token'] || request.headers['X-Spree-Order-Token'] || params[:order_token]
|
22
22
|
end
|
23
23
|
|
24
24
|
def spree_current_order
|
@@ -142,11 +142,15 @@ module Spree
|
|
142
142
|
}
|
143
143
|
end
|
144
144
|
|
145
|
-
def record_not_found
|
145
|
+
def record_not_found(exception)
|
146
|
+
result = error_handler.call(exception: exception, opts: { user: spree_current_user })
|
147
|
+
|
146
148
|
render_error_payload(I18n.t(:resource_not_found, scope: 'spree.api'), 404)
|
147
149
|
end
|
148
150
|
|
149
151
|
def access_denied(exception)
|
152
|
+
result = error_handler.call(exception: exception, opts: { user: spree_current_user })
|
153
|
+
|
150
154
|
render_error_payload(exception.message, 403)
|
151
155
|
end
|
152
156
|
|
@@ -155,6 +159,8 @@ module Spree
|
|
155
159
|
end
|
156
160
|
|
157
161
|
def gateway_error(exception)
|
162
|
+
result = error_handler.call(exception: exception, opts: { user: spree_current_user })
|
163
|
+
|
158
164
|
render_error_payload(exception.message)
|
159
165
|
end
|
160
166
|
|
@@ -16,7 +16,14 @@ module Spree
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def resource
|
19
|
-
|
19
|
+
# fixed N+1 queries issue
|
20
|
+
variant_includes = [
|
21
|
+
:prices,
|
22
|
+
{ option_values: [:option_type] }
|
23
|
+
]
|
24
|
+
|
25
|
+
# using FriendlyId so old slugs still work
|
26
|
+
@resource ||= find_with_fallback_default_locale { scope.includes(variants: variant_includes, master: variant_includes).friendly.find(params[:id]) } || scope.includes(variants: variant_includes, master: variant_includes).friendly.find(params[:id])
|
20
27
|
end
|
21
28
|
|
22
29
|
def collection_sorter
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Storefront
|
5
|
+
class VariantsController < ::Spree::Api::V2::ResourceController
|
6
|
+
private
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
Spree::Variant
|
10
|
+
end
|
11
|
+
|
12
|
+
def scope
|
13
|
+
product_scope = Spree::Product.for_store(current_store)
|
14
|
+
product_scope = product_scope.accessible_by(current_ability, :show)
|
15
|
+
product_scope = product_scope.i18n if model_class.include?(TranslatableResource)
|
16
|
+
|
17
|
+
product = product_scope.friendly.find(params[:id])
|
18
|
+
product.variants_including_master
|
19
|
+
end
|
20
|
+
|
21
|
+
def collection_finder
|
22
|
+
Spree::Api::Dependencies.storefront_variant_finder.constantize
|
23
|
+
end
|
24
|
+
|
25
|
+
def collection_serializer
|
26
|
+
Spree::Api::Dependencies.storefront_variant_serializer.constantize
|
27
|
+
end
|
28
|
+
|
29
|
+
def scope_includes
|
30
|
+
variant_includes = {
|
31
|
+
prices: [],
|
32
|
+
option_values: :option_type,
|
33
|
+
}
|
34
|
+
variant_includes[:images] = [] if params[:include]&.match(/images/)
|
35
|
+
variant_includes
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -100,6 +100,41 @@ module Spree
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
def add_items
|
104
|
+
spree_authorize! :create, Spree::WishedItem
|
105
|
+
|
106
|
+
@wished_items = resource.wished_items
|
107
|
+
ApplicationRecord.transaction do
|
108
|
+
wished_items_attributes.each do |wished_item_attributes|
|
109
|
+
wished_item = @wished_items.find_by(variant_id: wished_item_attributes[:variant_id])
|
110
|
+
|
111
|
+
if wished_item
|
112
|
+
wished_item.update!(quantity: wished_item_attributes[:quantity] || 1)
|
113
|
+
else
|
114
|
+
Spree::WishedItem.create!(wished_item_attributes.merge(wishlist: resource))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
resource.reload
|
120
|
+
render_serialized_payload { serialize_resource(resource) }
|
121
|
+
rescue ActiveRecord::RecordInvalid => e
|
122
|
+
render json: { error: e.record.errors.full_messages.to_sentence }, status: 422
|
123
|
+
end
|
124
|
+
|
125
|
+
def remove_items
|
126
|
+
spree_authorize! :destroy, Spree::WishedItem
|
127
|
+
|
128
|
+
ApplicationRecord.transaction do
|
129
|
+
resource.wished_items.where(id: wished_items_ids).each(&:destroy!)
|
130
|
+
end
|
131
|
+
|
132
|
+
resource.reload
|
133
|
+
render_serialized_payload { serialize_resource(resource) }
|
134
|
+
rescue ActiveRecord::RecordNotDestroyed => e
|
135
|
+
render json: { error: e.record.errors.full_messages.to_sentence }, status: 422
|
136
|
+
end
|
137
|
+
|
103
138
|
private
|
104
139
|
|
105
140
|
def scope(skip_cancancan: true)
|
@@ -164,6 +199,14 @@ module Spree
|
|
164
199
|
1
|
165
200
|
end
|
166
201
|
end
|
202
|
+
|
203
|
+
def wished_items_attributes
|
204
|
+
params.permit(wished_items: permitted_wished_item_attributes).require(:wished_items)
|
205
|
+
end
|
206
|
+
|
207
|
+
def wished_items_ids
|
208
|
+
params.require(:wished_items_ids)
|
209
|
+
end
|
167
210
|
end
|
168
211
|
end
|
169
212
|
end
|
@@ -10,13 +10,15 @@ module Spree
|
|
10
10
|
|
11
11
|
def queue_webhooks_requests!(event_name)
|
12
12
|
return if disable_spree_webhooks?
|
13
|
-
return if
|
14
|
-
return if Spree::Webhooks::Subscriber.active.with_urls_for(event_name).none?
|
13
|
+
return if no_webhooks_subscribers?(event_name)
|
15
14
|
return if update_event?(event_name) && updating_only_ignored_attributes?
|
16
15
|
return if webhook_payload_body.blank?
|
17
16
|
|
18
17
|
Spree::Webhooks::Subscribers::QueueRequests.call(
|
19
|
-
|
18
|
+
record: self,
|
19
|
+
event_name: event_name,
|
20
|
+
webhook_payload_body: webhook_payload_body,
|
21
|
+
**webhooks_request_options
|
20
22
|
)
|
21
23
|
end
|
22
24
|
|
@@ -43,7 +45,9 @@ module Spree
|
|
43
45
|
end
|
44
46
|
|
45
47
|
def included_relationships
|
46
|
-
if
|
48
|
+
if self.class.respond_to?(:webhook_included_relationships)
|
49
|
+
self.class.webhook_included_relationships
|
50
|
+
elsif resource_serializer.relationships_to_serialize
|
47
51
|
resource_serializer.relationships_to_serialize.keys
|
48
52
|
else
|
49
53
|
[]
|
@@ -74,7 +78,11 @@ module Spree
|
|
74
78
|
end
|
75
79
|
|
76
80
|
def disable_spree_webhooks?
|
77
|
-
|
81
|
+
Spree::Webhooks.disabled?
|
82
|
+
end
|
83
|
+
|
84
|
+
def no_webhooks_subscribers?(event_name)
|
85
|
+
!Spree::Webhooks::Subscriber.active.with_urls_for(event_name).exists?
|
78
86
|
end
|
79
87
|
|
80
88
|
def webhooks_request_options
|
@@ -6,6 +6,13 @@ module Spree
|
|
6
6
|
|
7
7
|
before_validation :set_blank_for_redirect_uri
|
8
8
|
|
9
|
+
# returns the last someone used this application
|
10
|
+
#
|
11
|
+
# @return [DateTime]
|
12
|
+
def last_used_at
|
13
|
+
access_tokens.order(:created_at).last&.created_at
|
14
|
+
end
|
15
|
+
|
9
16
|
private
|
10
17
|
|
11
18
|
def set_blank_for_redirect_uri
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Spree
|
2
|
+
class Order < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_update_commit :queue_webhooks_requests_for_order_resumed!
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def custom_webhook_events
|
13
|
+
%w[order.canceled order.placed order.resumed order.shipped]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_order_canceled_webhook
|
18
|
+
queue_webhooks_requests!('order.canceled')
|
19
|
+
end
|
20
|
+
|
21
|
+
def send_order_placed_webhook
|
22
|
+
queue_webhooks_requests!('order.placed')
|
23
|
+
end
|
24
|
+
|
25
|
+
def send_order_resumed_webhook
|
26
|
+
queue_webhooks_requests!('order.resumed')
|
27
|
+
self.state_machine_resumed = false # to not fire the same webhook twice
|
28
|
+
end
|
29
|
+
|
30
|
+
def queue_webhooks_requests_for_order_resumed!
|
31
|
+
return if state_machine_resumed?
|
32
|
+
return unless state_previously_changed?
|
33
|
+
return unless state_previous_change&.last == 'resumed'
|
34
|
+
|
35
|
+
send_order_resumed_webhook
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Spree
|
2
|
+
class Payment < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def custom_webhook_events
|
9
|
+
%w[payment.paid payment.voided]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def send_payment_voided_webhook
|
14
|
+
queue_webhooks_requests!('payment.voided')
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_payment_completed_webhook
|
18
|
+
queue_webhooks_requests!('payment.paid')
|
19
|
+
order.queue_webhooks_requests!('order.paid') if order.paid?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Spree
|
2
|
+
class Product < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_update_commit :queue_webhooks_requests_for_product_discontinued!
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def custom_webhook_events
|
13
|
+
%w[product.back_in_stock product.backorderable product.discontinued
|
14
|
+
product.out_of_stock product.activated product.archived product.drafted]
|
15
|
+
end
|
16
|
+
|
17
|
+
def ignored_attributes_for_update_webhook_event
|
18
|
+
%w[status]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def send_product_activated_webhook
|
23
|
+
queue_webhooks_requests!('product.activated')
|
24
|
+
end
|
25
|
+
|
26
|
+
def send_product_archived_webhook
|
27
|
+
queue_webhooks_requests!('product.archived')
|
28
|
+
end
|
29
|
+
|
30
|
+
def send_product_drafted_webhook
|
31
|
+
queue_webhooks_requests!('product.drafted')
|
32
|
+
end
|
33
|
+
|
34
|
+
def queue_webhooks_requests_for_product_discontinued!
|
35
|
+
return unless discontinue_on_previously_changed?
|
36
|
+
return if (change = discontinue_on_previous_change).blank? || change.last.blank?
|
37
|
+
|
38
|
+
queue_webhooks_requests!('product.discontinued')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spree
|
2
|
+
class Shipment < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def custom_webhook_events
|
9
|
+
%w[shipment.shipped]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def send_shipment_shipped_webhook
|
14
|
+
queue_webhooks_requests!('shipment.shipped')
|
15
|
+
order.queue_webhooks_requests!('order.shipped') if order.fully_shipped?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Spree
|
2
|
+
class StockItem < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
included do
|
8
|
+
around_save :queue_webhooks_requests_for_variant_backorderable!
|
9
|
+
around_save :queue_webhooks_requests_for_product_backorderable!
|
10
|
+
end
|
11
|
+
|
12
|
+
def queue_webhooks_requests_for_variant_backorderable!
|
13
|
+
was_out_of_stock = !variant.in_stock_or_backorderable?
|
14
|
+
was_not_backorderable = !variant_backorderable?
|
15
|
+
yield
|
16
|
+
if was_out_of_stock && was_not_backorderable && variant_backorderable?
|
17
|
+
reload
|
18
|
+
variant.queue_webhooks_requests!('variant.backorderable')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def queue_webhooks_requests_for_product_backorderable!
|
23
|
+
product_was_out_of_stock = !product.any_variant_in_stock_or_backorderable?
|
24
|
+
product_was_not_backorderable = !product_backorderable?
|
25
|
+
yield
|
26
|
+
if product_was_out_of_stock && product_was_not_backorderable && product_backorderable?
|
27
|
+
variant.product.queue_webhooks_requests!('product.backorderable')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def product_backorderable?
|
32
|
+
Spree::StockItem.exists?(backorderable: true, variant_id: variant.product.variants.ids)
|
33
|
+
end
|
34
|
+
|
35
|
+
def variant_backorderable?
|
36
|
+
variant.stock_items.exists?(backorderable: true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Spree
|
2
|
+
class StockMovement < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
included do
|
8
|
+
around_save :queue_webhooks_requests_for_variant_out_of_stock!
|
9
|
+
around_save :queue_webhooks_requests_for_variant_back_in_stock!
|
10
|
+
around_save :queue_webhooks_requests_for_product_out_of_stock!
|
11
|
+
around_save :queue_webhooks_requests_for_product_back_in_stock!
|
12
|
+
end
|
13
|
+
|
14
|
+
def queue_webhooks_requests_for_variant_out_of_stock!
|
15
|
+
variant_in_stock_before_update = variant.in_stock_or_backorderable?
|
16
|
+
yield
|
17
|
+
if variant_in_stock_before_update && !variant.in_stock_or_backorderable?
|
18
|
+
reload
|
19
|
+
stock_item.variant.queue_webhooks_requests!('variant.out_of_stock')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def queue_webhooks_requests_for_variant_back_in_stock!
|
24
|
+
variant_was_out_of_stock = !variant.in_stock_or_backorderable?
|
25
|
+
yield
|
26
|
+
if variant_was_out_of_stock && variant.in_stock_or_backorderable?
|
27
|
+
reload
|
28
|
+
variant.queue_webhooks_requests!('variant.back_in_stock')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def queue_webhooks_requests_for_product_back_in_stock!
|
33
|
+
product_was_out_of_stock = !product.any_variant_in_stock_or_backorderable?
|
34
|
+
yield
|
35
|
+
if product_was_out_of_stock && product.any_variant_in_stock_or_backorderable?
|
36
|
+
product.queue_webhooks_requests!('product.back_in_stock')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def queue_webhooks_requests_for_product_out_of_stock!
|
41
|
+
product_was_in_stock = product.any_variant_in_stock_or_backorderable?
|
42
|
+
yield
|
43
|
+
if product_was_in_stock && !product.any_variant_in_stock_or_backorderable?
|
44
|
+
product.queue_webhooks_requests!('product.out_of_stock')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Spree
|
2
|
+
class Variant < Spree::Base
|
3
|
+
module Webhooks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Spree::Webhooks::HasWebhooks
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_update_commit :queue_webhooks_requests_for_variant_discontinued!
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def custom_webhook_events
|
13
|
+
%w[variant.back_in_stock variant.backorderable variant.discontinued variant.out_of_stock]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def queue_webhooks_requests_for_variant_discontinued!
|
18
|
+
return unless discontinue_on_previously_changed?
|
19
|
+
return if (change = discontinue_on_previous_change).blank? || change.last.blank?
|
20
|
+
|
21
|
+
queue_webhooks_requests!('variant.discontinued')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -5,6 +5,7 @@ module Spree
|
|
5
5
|
class RefundSerializer < BaseSerializer
|
6
6
|
include ResourceSerializerConcern
|
7
7
|
|
8
|
+
belongs_to :refunder, serializer: Dependencies.platform_admin_user_serializer.constantize
|
8
9
|
belongs_to :payment
|
9
10
|
belongs_to :reimbursement
|
10
11
|
belongs_to :refund_reason, object_method_name: :reason
|
@@ -6,7 +6,7 @@ module Spree
|
|
6
6
|
include ResourceSerializerConcern
|
7
7
|
|
8
8
|
belongs_to :user
|
9
|
-
belongs_to :created_by, serializer:
|
9
|
+
belongs_to :created_by, serializer: Dependencies.platform_admin_user_serializer.constantize
|
10
10
|
belongs_to :store_credit_category, object_method_name: :category, id_method_name: :category_id
|
11
11
|
belongs_to :store_credit_type, object_method_name: :credit_type, id_method_name: :type_id
|
12
12
|
|
@@ -32,6 +32,7 @@ module Spree
|
|
32
32
|
def report_error(exception:, message:, opts:)
|
33
33
|
# overwrite this method in your application to support different error handlers
|
34
34
|
# eg. Sentry, Rollbar, etc
|
35
|
+
Sentry.capture_exception(exception) if defined?(Sentry)
|
35
36
|
|
36
37
|
success(exception: exception, message: message)
|
37
38
|
end
|
@@ -19,7 +19,7 @@ module Spree
|
|
19
19
|
end
|
20
20
|
return process(:warn, msg("failed for '#{url}'")) if request.failed_request?
|
21
21
|
|
22
|
-
process
|
22
|
+
process
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -30,8 +30,8 @@ module Spree
|
|
30
30
|
delegate :id, :url, to: :subscriber
|
31
31
|
delegate :created_at, :id, to: :event, prefix: true
|
32
32
|
|
33
|
-
def process(log_level, msg)
|
34
|
-
Rails.logger.public_send(log_level, msg)
|
33
|
+
def process(log_level = nil, msg = nil)
|
34
|
+
Rails.logger.public_send(log_level, msg) if msg.present? && log_level.present?
|
35
35
|
make_request
|
36
36
|
update_event(msg)
|
37
37
|
nil
|
@@ -59,7 +59,7 @@ module Spree
|
|
59
59
|
)
|
60
60
|
end
|
61
61
|
|
62
|
-
def update_event(msg)
|
62
|
+
def update_event(msg = nil)
|
63
63
|
event.update(
|
64
64
|
execution_time: execution_time,
|
65
65
|
request_errors: msg,
|
@@ -45,7 +45,7 @@ module Spree
|
|
45
45
|
def http
|
46
46
|
http = Net::HTTP.new(uri_host, uri_port)
|
47
47
|
http.read_timeout = webhooks_timeout.to_i if custom_read_timeout?
|
48
|
-
http.use_ssl =
|
48
|
+
http.use_ssl = use_ssl?
|
49
49
|
http
|
50
50
|
end
|
51
51
|
|
@@ -71,7 +71,7 @@ module Spree
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def use_ssl?
|
74
|
-
|
74
|
+
uri.scheme == 'https'
|
75
75
|
end
|
76
76
|
|
77
77
|
def uri
|
@@ -4,8 +4,8 @@ module Spree
|
|
4
4
|
class QueueRequests
|
5
5
|
prepend Spree::ServiceModule::Base
|
6
6
|
|
7
|
-
def call(event_name:, webhook_payload_body:, **options)
|
8
|
-
filtered_subscribers(event_name, webhook_payload_body, options).each do |subscriber|
|
7
|
+
def call(event_name:, webhook_payload_body:, record: nil, **options)
|
8
|
+
filtered_subscribers(event_name, webhook_payload_body, record, options).each do |subscriber|
|
9
9
|
Spree::Webhooks::Subscribers::MakeRequestJob.perform_later(
|
10
10
|
webhook_payload_body, event_name, subscriber
|
11
11
|
)
|
@@ -14,7 +14,7 @@ module Spree
|
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
|
-
def filtered_subscribers(event_name,
|
17
|
+
def filtered_subscribers(event_name, webhook_payload_body, record, options)
|
18
18
|
Spree::Webhooks::Subscriber.active.with_urls_for(event_name)
|
19
19
|
end
|
20
20
|
end
|
@@ -45,4 +45,6 @@ Doorkeeper.configure do
|
|
45
45
|
# using Bcrupt for token secrets is currently not supported by Doorkeeper
|
46
46
|
hash_token_secrets fallback: :plain
|
47
47
|
hash_application_secrets fallback: :plain, using: '::Doorkeeper::SecretStoring::BCrypt'
|
48
|
+
|
49
|
+
access_token_expires_in 1.month
|
48
50
|
end
|
data/config/routes.rb
CHANGED
@@ -14,7 +14,7 @@ Spree::Core::Engine.add_routes do
|
|
14
14
|
delete 'remove_line_item/:line_item_id', to: 'cart#remove_line_item', as: :cart_remove_line_item
|
15
15
|
patch :set_quantity
|
16
16
|
patch :apply_coupon_code
|
17
|
-
delete 'remove_coupon_code/:coupon_code', to: 'cart#remove_coupon_code', as: :cart_remove_coupon_code
|
17
|
+
delete 'remove_coupon_code/:coupon_code', to: 'cart#remove_coupon_code', as: :cart_remove_coupon_code, constraints: { coupon_code: /[^\/]+/ }
|
18
18
|
delete 'remove_coupon_code', to: 'cart#remove_coupon_code', as: :cart_remove_coupon_code_without_code
|
19
19
|
get :estimate_shipping_rates
|
20
20
|
patch :associate
|
@@ -45,6 +45,7 @@ Spree::Core::Engine.add_routes do
|
|
45
45
|
get '/countries/:iso', to: 'countries#show', as: :country
|
46
46
|
get '/order_status/:number', to: 'order_status#show', as: :order_status
|
47
47
|
resources :products, only: %i[index show]
|
48
|
+
get '/products/:id/variants', to: 'variants#index', as: :product_variants
|
48
49
|
resources :taxons, only: %i[index show], id: /.+/
|
49
50
|
get '/stores/:code', to: 'stores#show', as: :store
|
50
51
|
get '/store', to: 'stores#current', as: :current_store
|
@@ -59,6 +60,8 @@ Spree::Core::Engine.add_routes do
|
|
59
60
|
post :add_item
|
60
61
|
patch 'set_item_quantity/:item_id', to: 'wishlists#set_item_quantity', as: :set_item_quantity
|
61
62
|
delete 'remove_item/:item_id', to: 'wishlists#remove_item', as: :remove_item
|
63
|
+
post :add_items
|
64
|
+
delete :remove_items
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'spree/core/preferences/runtime_configuration'
|
2
|
+
|
1
3
|
module Spree
|
2
4
|
module Api
|
3
|
-
class Configuration < Preferences::
|
5
|
+
class Configuration < Spree::Preferences::RuntimeConfiguration
|
4
6
|
preference :api_v2_serializers_cache_ttl, :integer, default: 3600 # 1 hour in seconds
|
5
7
|
preference :api_v2_collection_cache_ttl, :integer, default: 3600 # 1 hour in seconds
|
6
8
|
preference :api_v2_collection_cache_namespace, :string, default: 'api_v2_collection_cache'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spree/core/dependencies_helper'
|
2
|
+
|
1
3
|
module Spree
|
2
4
|
module Api
|
3
5
|
class ApiDependencies
|
@@ -60,6 +62,7 @@ module Spree
|
|
60
62
|
storefront_estimated_shipment_serializer: 'Spree::V2::Storefront::EstimatedShippingRateSerializer',
|
61
63
|
storefront_store_serializer: 'Spree::V2::Storefront::StoreSerializer',
|
62
64
|
storefront_order_serializer: 'Spree::V2::Storefront::OrderSerializer',
|
65
|
+
storefront_variant_serializer: 'Spree::V2::Storefront::VariantSerializer',
|
63
66
|
|
64
67
|
# sorters
|
65
68
|
storefront_collection_sorter: -> { Spree::Dependencies.collection_sorter },
|
@@ -81,11 +84,12 @@ module Spree
|
|
81
84
|
storefront_find_by_variant_finder: -> { Spree::Dependencies.line_item_by_variant_finder },
|
82
85
|
storefront_products_finder: -> { Spree::Dependencies.products_finder },
|
83
86
|
storefront_taxon_finder: -> { Spree::Dependencies.taxon_finder },
|
87
|
+
storefront_variant_finder: -> { Spree::Dependencies.variant_finder },
|
84
88
|
|
85
89
|
error_handler: 'Spree::Api::ErrorHandler',
|
86
90
|
|
87
91
|
# serializers
|
88
|
-
platform_admin_user_serializer: 'Spree::Api::V2::Platform::
|
92
|
+
platform_admin_user_serializer: 'Spree::Api::V2::Platform::AdminUserSerializer',
|
89
93
|
|
90
94
|
# coupon code handler
|
91
95
|
platform_coupon_handler: -> { Spree::Dependencies.coupon_handler },
|
data/lib/spree/api/engine.rb
CHANGED
@@ -18,17 +18,9 @@ module Spree
|
|
18
18
|
Migrations.new(config, engine_name).check
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.activate
|
22
|
-
Dir.glob(File.join(File.dirname(__FILE__), '../../../app/models/spree/api/webhooks/*_decorator*.rb')) do |c|
|
23
|
-
Rails.application.config.cache_classes ? require(c) : load(c)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
21
|
def self.root
|
28
22
|
@root ||= Pathname.new(File.expand_path('../../..', __dir__))
|
29
23
|
end
|
30
|
-
|
31
|
-
config.to_prepare &method(:activate).to_proc
|
32
24
|
end
|
33
25
|
end
|
34
26
|
end
|
@@ -26,7 +26,7 @@
|
|
26
26
|
# isn't added to the matcher definition, because it acts in a different
|
27
27
|
# way depending on what's the resource being tested.
|
28
28
|
#
|
29
|
-
RSpec::Matchers.define :emit_webhook_event do |event_to_emit|
|
29
|
+
RSpec::Matchers.define :emit_webhook_event do |event_to_emit, record = nil|
|
30
30
|
match do |block|
|
31
31
|
queue_requests = instance_double(Spree::Webhooks::Subscribers::QueueRequests)
|
32
32
|
|
@@ -36,7 +36,7 @@ RSpec::Matchers.define :emit_webhook_event do |event_to_emit|
|
|
36
36
|
with_webhooks_enabled { Timecop.freeze { block.call } }
|
37
37
|
|
38
38
|
expect(queue_requests).to(
|
39
|
-
have_received(:call).with(event_name: event_to_emit, webhook_payload_body: webhook_payload_body.to_json).once
|
39
|
+
have_received(:call).with(event_name: event_to_emit, webhook_payload_body: webhook_payload_body.to_json, record: record).once
|
40
40
|
)
|
41
41
|
end
|
42
42
|
|
@@ -61,7 +61,7 @@ RSpec::Matchers.define :emit_webhook_event do |event_to_emit|
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def with_webhooks_enabled
|
64
|
-
|
64
|
+
Spree::Webhooks.disabled = false
|
65
65
|
yield
|
66
|
-
|
66
|
+
Spree::Webhooks.disabled = true
|
67
67
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
RSpec.configure do |config|
|
2
2
|
config.before(:each, :spree_webhooks) do
|
3
|
-
|
3
|
+
Spree::Webhooks.disabled = false
|
4
4
|
end
|
5
5
|
|
6
6
|
config.after(:each, :spree_webhooks) do
|
7
|
-
|
7
|
+
Spree::Webhooks.disabled = true
|
8
8
|
end
|
9
9
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Bigg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n-tasks
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 4.
|
117
|
+
version: 4.9.0
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 4.
|
124
|
+
version: 4.9.0
|
125
125
|
description: Spree's API
|
126
126
|
email:
|
127
127
|
- ryan@spreecommerce.com
|
@@ -203,6 +203,7 @@ files:
|
|
203
203
|
- app/controllers/spree/api/v2/storefront/products_controller.rb
|
204
204
|
- app/controllers/spree/api/v2/storefront/stores_controller.rb
|
205
205
|
- app/controllers/spree/api/v2/storefront/taxons_controller.rb
|
206
|
+
- app/controllers/spree/api/v2/storefront/variants_controller.rb
|
206
207
|
- app/controllers/spree/api/v2/storefront/wishlists_controller.rb
|
207
208
|
- app/helpers/spree/api/v2/collection_options_helpers.rb
|
208
209
|
- app/helpers/spree/api/v2/display_money_helper.rb
|
@@ -211,16 +212,16 @@ files:
|
|
211
212
|
- app/models/concerns/spree/user_api_authentication.rb
|
212
213
|
- app/models/concerns/spree/user_api_methods.rb
|
213
214
|
- app/models/concerns/spree/webhooks/has_webhooks.rb
|
214
|
-
- app/models/spree/api/webhooks/order_decorator.rb
|
215
|
-
- app/models/spree/api/webhooks/payment_decorator.rb
|
216
|
-
- app/models/spree/api/webhooks/product_decorator.rb
|
217
|
-
- app/models/spree/api/webhooks/shipment_decorator.rb
|
218
|
-
- app/models/spree/api/webhooks/stock_item_decorator.rb
|
219
|
-
- app/models/spree/api/webhooks/stock_movement_decorator.rb
|
220
|
-
- app/models/spree/api/webhooks/variant_decorator.rb
|
221
215
|
- app/models/spree/oauth_access_grant.rb
|
222
216
|
- app/models/spree/oauth_access_token.rb
|
223
217
|
- app/models/spree/oauth_application.rb
|
218
|
+
- app/models/spree/order/webhooks.rb
|
219
|
+
- app/models/spree/payment/webhooks.rb
|
220
|
+
- app/models/spree/product/webhooks.rb
|
221
|
+
- app/models/spree/shipment/webhooks.rb
|
222
|
+
- app/models/spree/stock_item/webhooks.rb
|
223
|
+
- app/models/spree/stock_movement/webhooks.rb
|
224
|
+
- app/models/spree/variant/webhooks.rb
|
224
225
|
- app/models/spree/webhooks/base.rb
|
225
226
|
- app/models/spree/webhooks/event.rb
|
226
227
|
- app/models/spree/webhooks/event_signature.rb
|
@@ -232,6 +233,7 @@ files:
|
|
232
233
|
- app/serializers/spree/api/v2/base_serializer.rb
|
233
234
|
- app/serializers/spree/api/v2/platform/address_serializer.rb
|
234
235
|
- app/serializers/spree/api/v2/platform/adjustment_serializer.rb
|
236
|
+
- app/serializers/spree/api/v2/platform/admin_user_serializer.rb
|
235
237
|
- app/serializers/spree/api/v2/platform/asset_serializer.rb
|
236
238
|
- app/serializers/spree/api/v2/platform/base_serializer.rb
|
237
239
|
- app/serializers/spree/api/v2/platform/calculator_serializer.rb
|
@@ -337,6 +339,8 @@ files:
|
|
337
339
|
- app/serializers/spree/v2/storefront/product_serializer.rb
|
338
340
|
- app/serializers/spree/v2/storefront/promotion_serializer.rb
|
339
341
|
- app/serializers/spree/v2/storefront/shipment_serializer.rb
|
342
|
+
- app/serializers/spree/v2/storefront/shipping_category_serializer.rb
|
343
|
+
- app/serializers/spree/v2/storefront/shipping_method_serializer.rb
|
340
344
|
- app/serializers/spree/v2/storefront/shipping_rate_serializer.rb
|
341
345
|
- app/serializers/spree/v2/storefront/state_serializer.rb
|
342
346
|
- app/serializers/spree/v2/storefront/stock_location_serializer.rb
|
@@ -402,9 +406,9 @@ licenses:
|
|
402
406
|
- BSD-3-Clause
|
403
407
|
metadata:
|
404
408
|
bug_tracker_uri: https://github.com/spree/spree/issues
|
405
|
-
changelog_uri: https://github.com/spree/spree/releases/tag/v4.
|
409
|
+
changelog_uri: https://github.com/spree/spree/releases/tag/v4.9.0
|
406
410
|
documentation_uri: https://docs.spreecommerce.org/
|
407
|
-
source_code_uri: https://github.com/spree/spree/tree/v4.
|
411
|
+
source_code_uri: https://github.com/spree/spree/tree/v4.9.0
|
408
412
|
post_install_message:
|
409
413
|
rdoc_options: []
|
410
414
|
require_paths:
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module OrderDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
def base.custom_webhook_events
|
7
|
-
%w[order.canceled order.placed order.resumed order.shipped]
|
8
|
-
end
|
9
|
-
|
10
|
-
base.after_update_commit :queue_webhooks_requests_for_order_resumed!
|
11
|
-
end
|
12
|
-
|
13
|
-
def after_cancel
|
14
|
-
super
|
15
|
-
queue_webhooks_requests!('order.canceled')
|
16
|
-
end
|
17
|
-
|
18
|
-
def finalize!
|
19
|
-
super
|
20
|
-
queue_webhooks_requests!('order.placed')
|
21
|
-
end
|
22
|
-
|
23
|
-
def after_resume
|
24
|
-
super
|
25
|
-
queue_webhooks_requests!('order.resumed')
|
26
|
-
self.state_machine_resumed = false
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def queue_webhooks_requests_for_order_resumed!
|
32
|
-
return if state_machine_resumed?
|
33
|
-
return unless state_previously_changed?
|
34
|
-
return unless state_previous_change&.last == 'resumed'
|
35
|
-
|
36
|
-
queue_webhooks_requests!('order.resumed')
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
Spree::Order.prepend(Spree::Api::Webhooks::OrderDecorator)
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module PaymentDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
def base.custom_webhook_events
|
7
|
-
%w[payment.paid payment.voided]
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def after_void
|
12
|
-
super
|
13
|
-
queue_webhooks_requests!('payment.voided')
|
14
|
-
end
|
15
|
-
|
16
|
-
def after_completed
|
17
|
-
super
|
18
|
-
queue_webhooks_requests!('payment.paid')
|
19
|
-
order.queue_webhooks_requests!('order.paid') if order.paid?
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
Spree::Payment.prepend(Spree::Api::Webhooks::PaymentDecorator)
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module ProductDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
def base.custom_webhook_events
|
7
|
-
%w[product.back_in_stock product.backorderable product.discontinued
|
8
|
-
product.out_of_stock product.activated product.archived product.drafted]
|
9
|
-
end
|
10
|
-
|
11
|
-
def base.ignored_attributes_for_update_webhook_event
|
12
|
-
%w[status]
|
13
|
-
end
|
14
|
-
|
15
|
-
base.after_update_commit :queue_webhooks_requests_for_product_discontinued!
|
16
|
-
end
|
17
|
-
|
18
|
-
def after_activate
|
19
|
-
super
|
20
|
-
queue_webhooks_requests!('product.activated')
|
21
|
-
end
|
22
|
-
|
23
|
-
def after_archive
|
24
|
-
super
|
25
|
-
queue_webhooks_requests!('product.archived')
|
26
|
-
end
|
27
|
-
|
28
|
-
def after_draft
|
29
|
-
super
|
30
|
-
queue_webhooks_requests!('product.drafted')
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def queue_webhooks_requests_for_product_discontinued!
|
36
|
-
return unless discontinue_on_previously_changed?
|
37
|
-
return if (change = discontinue_on_previous_change).blank? || change.last.blank?
|
38
|
-
|
39
|
-
queue_webhooks_requests!('product.discontinued')
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
Spree::Product.prepend(Spree::Api::Webhooks::ProductDecorator)
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module ShipmentDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
def base.custom_webhook_events
|
7
|
-
%w[shipment.shipped]
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def after_ship
|
12
|
-
super
|
13
|
-
queue_webhooks_requests!('shipment.shipped')
|
14
|
-
order.queue_webhooks_requests!('order.shipped') if order.fully_shipped?
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
Spree::Shipment.prepend(Spree::Api::Webhooks::ShipmentDecorator)
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module StockItemDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
base.around_save :queue_webhooks_requests_for_variant_backorderable!
|
7
|
-
base.around_save :queue_webhooks_requests_for_product_backorderable!
|
8
|
-
end
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def queue_webhooks_requests_for_variant_backorderable!
|
13
|
-
was_out_of_stock = !variant.in_stock_or_backorderable?
|
14
|
-
was_not_backorderable = !variant_backorderable?
|
15
|
-
yield
|
16
|
-
if was_out_of_stock && was_not_backorderable && variant_backorderable?
|
17
|
-
reload
|
18
|
-
variant.queue_webhooks_requests!('variant.backorderable')
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def queue_webhooks_requests_for_product_backorderable!
|
23
|
-
product_was_out_of_stock = !product.any_variant_in_stock_or_backorderable?
|
24
|
-
product_was_not_backorderable = !product_backorderable?
|
25
|
-
yield
|
26
|
-
if product_was_out_of_stock && product_was_not_backorderable && product_backorderable?
|
27
|
-
variant.product.queue_webhooks_requests!('product.backorderable')
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def product_backorderable?
|
32
|
-
Spree::StockItem.exists?(backorderable: true, variant_id: variant.product.variants.ids)
|
33
|
-
end
|
34
|
-
|
35
|
-
def variant_backorderable?
|
36
|
-
variant.stock_items.exists?(backorderable: true)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
Spree::StockItem.prepend(Spree::Api::Webhooks::StockItemDecorator)
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module StockMovementDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
base.around_save :queue_webhooks_requests_for_variant_out_of_stock!
|
7
|
-
base.around_save :queue_webhooks_requests_for_variant_back_in_stock!
|
8
|
-
base.around_save :queue_webhooks_requests_for_product_out_of_stock!
|
9
|
-
base.around_save :queue_webhooks_requests_for_product_back_in_stock!
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def queue_webhooks_requests_for_variant_out_of_stock!
|
15
|
-
variant_in_stock_before_update = variant.in_stock_or_backorderable?
|
16
|
-
yield
|
17
|
-
if variant_in_stock_before_update && !variant.in_stock_or_backorderable?
|
18
|
-
reload
|
19
|
-
stock_item.variant.queue_webhooks_requests!('variant.out_of_stock')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def queue_webhooks_requests_for_variant_back_in_stock!
|
24
|
-
variant_was_out_of_stock = !variant.in_stock_or_backorderable?
|
25
|
-
yield
|
26
|
-
if variant_was_out_of_stock && variant.in_stock_or_backorderable?
|
27
|
-
reload
|
28
|
-
variant.queue_webhooks_requests!('variant.back_in_stock')
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def queue_webhooks_requests_for_product_back_in_stock!
|
33
|
-
product_was_out_of_stock = !product.any_variant_in_stock_or_backorderable?
|
34
|
-
yield
|
35
|
-
if product_was_out_of_stock && product.any_variant_in_stock_or_backorderable?
|
36
|
-
product.queue_webhooks_requests!('product.back_in_stock')
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def queue_webhooks_requests_for_product_out_of_stock!
|
41
|
-
product_was_in_stock = product.any_variant_in_stock_or_backorderable?
|
42
|
-
yield
|
43
|
-
if product_was_in_stock && !product.any_variant_in_stock_or_backorderable?
|
44
|
-
product.queue_webhooks_requests!('product.out_of_stock')
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
Spree::StockMovement.prepend(Spree::Api::Webhooks::StockMovementDecorator)
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Spree
|
2
|
-
module Api
|
3
|
-
module Webhooks
|
4
|
-
module VariantDecorator
|
5
|
-
def self.prepended(base)
|
6
|
-
def base.custom_webhook_events
|
7
|
-
%w[variant.back_in_stock variant.backorderable variant.discontinued variant.out_of_stock]
|
8
|
-
end
|
9
|
-
|
10
|
-
base.after_update_commit :queue_webhooks_requests_for_variant_discontinued!
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def queue_webhooks_requests_for_variant_discontinued!
|
16
|
-
return unless discontinue_on_previously_changed?
|
17
|
-
return if (change = discontinue_on_previous_change).blank? || change.last.blank?
|
18
|
-
|
19
|
-
queue_webhooks_requests!('variant.discontinued')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
Spree::Variant.prepend(Spree::Api::Webhooks::VariantDecorator)
|