spree_api 4.3.0 → 4.4.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.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/spree/api/v2/caching.rb +7 -3
  3. data/app/controllers/concerns/spree/api/v2/coupon_codes_helper.rb +29 -0
  4. data/app/controllers/concerns/spree/api/v2/number_resource.rb +11 -0
  5. data/app/controllers/concerns/spree/api/v2/platform/nested_set_reposition_concern.rb +37 -0
  6. data/app/controllers/concerns/spree/api/v2/platform/promotion_calculator_params.rb +17 -0
  7. data/app/controllers/concerns/spree/api/v2/platform/promotion_rule_params.rb +16 -0
  8. data/app/controllers/concerns/spree/api/v2/storefront/metadata_controller_concern.rb +18 -0
  9. data/app/controllers/spree/api/v1/checkouts_controller.rb +1 -1
  10. data/app/controllers/spree/api/v2/base_controller.rb +7 -5
  11. data/app/controllers/spree/api/v2/platform/adjustments_controller.rb +19 -0
  12. data/app/controllers/spree/api/v2/platform/classifications_controller.rb +1 -22
  13. data/app/controllers/spree/api/v2/platform/cms_pages_controller.rb +4 -0
  14. data/app/controllers/spree/api/v2/platform/cms_sections_controller.rb +13 -18
  15. data/app/controllers/spree/api/v2/platform/digital_links_controller.rb +25 -0
  16. data/app/controllers/spree/api/v2/platform/digitals_controller.rb +19 -0
  17. data/app/controllers/spree/api/v2/platform/line_items_controller.rb +59 -0
  18. data/app/controllers/spree/api/v2/platform/menu_items_controller.rb +5 -19
  19. data/app/controllers/spree/api/v2/platform/menus_controller.rb +0 -4
  20. data/app/controllers/spree/api/v2/platform/orders_controller.rb +163 -0
  21. data/app/controllers/spree/api/v2/platform/payment_methods_controller.rb +27 -0
  22. data/app/controllers/spree/api/v2/platform/payments_controller.rb +17 -0
  23. data/app/controllers/spree/api/v2/platform/promotion_actions_controller.rb +30 -0
  24. data/app/controllers/spree/api/v2/platform/promotion_categories_controller.rb +19 -0
  25. data/app/controllers/spree/api/v2/platform/promotion_rules_controller.rb +25 -0
  26. data/app/controllers/spree/api/v2/platform/promotions_controller.rb +31 -0
  27. data/app/controllers/spree/api/v2/platform/resource_controller.rb +47 -16
  28. data/app/controllers/spree/api/v2/platform/roles_controller.rb +15 -0
  29. data/app/controllers/spree/api/v2/platform/shipments_controller.rb +143 -0
  30. data/app/controllers/spree/api/v2/platform/shipping_categories_controller.rb +15 -0
  31. data/app/controllers/spree/api/v2/platform/shipping_methods_controller.rb +24 -0
  32. data/app/controllers/spree/api/v2/platform/states_controller.rb +19 -0
  33. data/app/controllers/spree/api/v2/platform/stock_items_controller.rb +19 -0
  34. data/app/controllers/spree/api/v2/platform/stock_locations_controller.rb +19 -0
  35. data/app/controllers/spree/api/v2/platform/store_credit_categories_controller.rb +15 -0
  36. data/app/controllers/spree/api/v2/platform/store_credit_types_controller.rb +15 -0
  37. data/app/controllers/spree/api/v2/platform/store_credits_controller.rb +19 -0
  38. data/app/controllers/spree/api/v2/platform/tax_categories_controller.rb +19 -0
  39. data/app/controllers/spree/api/v2/platform/tax_rates_controller.rb +23 -0
  40. data/app/controllers/spree/api/v2/platform/taxonomies_controller.rb +19 -0
  41. data/app/controllers/spree/api/v2/platform/taxons_controller.rb +25 -0
  42. data/app/controllers/spree/api/v2/platform/users_controller.rb +4 -0
  43. data/app/controllers/spree/api/v2/platform/variants_controller.rb +19 -0
  44. data/app/controllers/spree/api/v2/platform/webhooks/events_controller.rb +21 -0
  45. data/app/controllers/spree/api/v2/platform/webhooks/subscribers_controller.rb +21 -0
  46. data/app/controllers/spree/api/v2/platform/wished_items_controller.rb +19 -0
  47. data/app/controllers/spree/api/v2/platform/wishlists_controller.rb +19 -0
  48. data/app/controllers/spree/api/v2/platform/zones_controller.rb +19 -0
  49. data/app/controllers/spree/api/v2/resource_controller.rb +3 -3
  50. data/app/controllers/spree/api/v2/storefront/account/addresses_controller.rb +2 -2
  51. data/app/controllers/spree/api/v2/storefront/account/credit_cards_controller.rb +4 -1
  52. data/app/controllers/spree/api/v2/storefront/cart_controller.rb +18 -28
  53. data/app/controllers/spree/api/v2/storefront/checkout_controller.rb +24 -0
  54. data/app/controllers/spree/api/v2/storefront/digitals_controller.rb +54 -0
  55. data/app/controllers/spree/api/v2/storefront/wishlists_controller.rb +171 -0
  56. data/app/helpers/spree/api/v2/collection_options_helpers.rb +1 -1
  57. data/app/jobs/spree/webhooks/subscribers/make_request_job.rb +17 -0
  58. data/app/models/concerns/spree/webhooks/has_webhooks.rb +60 -0
  59. data/app/models/spree/api/webhooks/order_decorator.rb +43 -0
  60. data/app/models/spree/api/webhooks/payment_decorator.rb +26 -0
  61. data/app/models/spree/api/webhooks/product_decorator.rb +27 -0
  62. data/app/models/spree/api/webhooks/shipment_decorator.rb +21 -0
  63. data/app/models/spree/api/webhooks/stock_item_decorator.rb +43 -0
  64. data/app/models/spree/api/webhooks/stock_movement_decorator.rb +52 -0
  65. data/app/models/spree/api/webhooks/variant_decorator.rb +26 -0
  66. data/app/models/spree/oauth_access_grant.rb +7 -0
  67. data/app/models/spree/oauth_access_token.rb +7 -0
  68. data/app/models/spree/oauth_application.rb +15 -0
  69. data/app/models/spree/webhooks/base.rb +11 -0
  70. data/app/models/spree/webhooks/event.rb +12 -0
  71. data/app/models/spree/webhooks/subscriber.rb +57 -0
  72. data/app/serializers/concerns/spree/api/v2/resource_serializer_concern.rb +19 -1
  73. data/app/serializers/spree/api/v2/base_serializer.rb +11 -4
  74. data/app/serializers/spree/api/v2/platform/address_serializer.rb +1 -1
  75. data/app/serializers/spree/api/v2/platform/adjustment_serializer.rb +20 -0
  76. data/app/serializers/spree/api/v2/platform/asset_serializer.rb +13 -0
  77. data/app/serializers/spree/api/v2/platform/calculator_serializer.rb +17 -0
  78. data/app/serializers/spree/api/v2/platform/classification_serializer.rb +1 -1
  79. data/app/serializers/spree/api/v2/platform/cms_page_serializer.rb +1 -1
  80. data/app/serializers/spree/api/v2/platform/cms_section_serializer.rb +8 -1
  81. data/app/serializers/spree/api/v2/platform/country_serializer.rb +1 -1
  82. data/app/serializers/spree/api/v2/platform/credit_card_serializer.rb +14 -0
  83. data/app/serializers/spree/api/v2/platform/customer_return_serializer.rb +17 -0
  84. data/app/serializers/spree/api/v2/platform/digital_link_serializer.rb +16 -0
  85. data/app/serializers/spree/api/v2/platform/digital_serializer.rb +30 -0
  86. data/app/serializers/spree/api/v2/platform/feature_page_serializer.rb +11 -0
  87. data/app/serializers/spree/api/v2/platform/homepage_serializer.rb +11 -0
  88. data/app/serializers/spree/api/v2/platform/inventory_unit_serializer.rb +19 -0
  89. data/app/serializers/spree/api/v2/platform/line_item_serializer.rb +19 -0
  90. data/app/serializers/spree/api/v2/platform/log_entry_serializer.rb +13 -0
  91. data/app/serializers/spree/api/v2/platform/menu_item_serializer.rb +1 -1
  92. data/app/serializers/spree/api/v2/platform/menu_serializer.rb +1 -1
  93. data/app/serializers/spree/api/v2/platform/option_type_serializer.rb +1 -1
  94. data/app/serializers/spree/api/v2/platform/option_value_serializer.rb +1 -1
  95. data/app/serializers/spree/api/v2/platform/order_promotion_serializer.rb +14 -0
  96. data/app/serializers/spree/api/v2/platform/order_serializer.rb +31 -0
  97. data/app/serializers/spree/api/v2/platform/payment_capture_event_serializer.rb +13 -0
  98. data/app/serializers/spree/api/v2/platform/payment_method_serializer.rb +18 -0
  99. data/app/serializers/spree/api/v2/platform/payment_serializer.rb +21 -0
  100. data/app/serializers/spree/api/v2/platform/price_serializer.rb +19 -0
  101. data/app/serializers/spree/api/v2/platform/product_property_serializer.rb +1 -1
  102. data/app/serializers/spree/api/v2/platform/product_serializer.rb +7 -3
  103. data/app/serializers/spree/api/v2/platform/promotion_action_line_item_serializer.rb +14 -0
  104. data/app/serializers/spree/api/v2/platform/promotion_action_serializer.rb +19 -0
  105. data/app/serializers/spree/api/v2/platform/promotion_category_serializer.rb +13 -0
  106. data/app/serializers/spree/api/v2/platform/promotion_rule_serializer.rb +21 -0
  107. data/app/serializers/spree/api/v2/platform/promotion_serializer.rb +17 -0
  108. data/app/serializers/spree/api/v2/platform/property_serializer.rb +11 -0
  109. data/app/serializers/spree/api/v2/platform/prototype_serializer.rb +15 -0
  110. data/app/serializers/spree/api/v2/platform/refund_reason_serializer.rb +11 -0
  111. data/app/serializers/spree/api/v2/platform/refund_serializer.rb +16 -0
  112. data/app/serializers/spree/api/v2/platform/reimbursement_credit_serializer.rb +10 -0
  113. data/app/serializers/spree/api/v2/platform/reimbursement_serializer.rb +18 -0
  114. data/app/serializers/spree/api/v2/platform/reimbursement_type_serializer.rb +11 -0
  115. data/app/serializers/spree/api/v2/platform/return_authorization_reason_serializer.rb +11 -0
  116. data/app/serializers/spree/api/v2/platform/return_authorization_serializer.rb +17 -0
  117. data/app/serializers/spree/api/v2/platform/return_item_serializer.rb +16 -0
  118. data/app/serializers/spree/api/v2/platform/role_serializer.rb +11 -0
  119. data/app/serializers/spree/api/v2/platform/shipment_serializer.rb +22 -0
  120. data/app/serializers/spree/api/v2/platform/shipping_category_serializer.rb +11 -0
  121. data/app/serializers/spree/api/v2/platform/shipping_method_serializer.rb +16 -0
  122. data/app/serializers/spree/api/v2/platform/shipping_rate_serializer.rb +15 -0
  123. data/app/serializers/spree/api/v2/platform/standard_page_serializer.rb +11 -0
  124. data/app/serializers/spree/api/v2/platform/state_change_serializer.rb +13 -0
  125. data/app/serializers/spree/api/v2/platform/state_serializer.rb +1 -1
  126. data/app/serializers/spree/api/v2/platform/stock_item_serializer.rb +1 -3
  127. data/app/serializers/spree/api/v2/platform/stock_location_serializer.rb +2 -4
  128. data/app/serializers/spree/api/v2/platform/stock_movement_serializer.rb +11 -0
  129. data/app/serializers/spree/api/v2/platform/stock_transfer_serializer.rb +15 -0
  130. data/app/serializers/spree/api/v2/platform/store_credit_category_serializer.rb +12 -0
  131. data/app/serializers/spree/api/v2/platform/store_credit_event_serializer.rb +14 -0
  132. data/app/serializers/spree/api/v2/platform/store_credit_serializer.rb +18 -0
  133. data/app/serializers/spree/api/v2/platform/store_credit_type_serializer.rb +12 -0
  134. data/app/serializers/spree/api/v2/platform/store_serializer.rb +1 -1
  135. data/app/serializers/spree/api/v2/platform/tax_category_serializer.rb +2 -2
  136. data/app/serializers/spree/api/v2/platform/tax_rate_serializer.rb +14 -0
  137. data/app/serializers/spree/api/v2/platform/taxon_serializer.rb +1 -1
  138. data/app/serializers/spree/api/v2/platform/taxonomy_serializer.rb +1 -1
  139. data/app/serializers/spree/api/v2/platform/user_serializer.rb +1 -1
  140. data/app/serializers/spree/api/v2/platform/variant_serializer.rb +3 -2
  141. data/app/serializers/spree/api/v2/platform/webhooks/event_serializer.rb +15 -0
  142. data/app/serializers/spree/api/v2/platform/webhooks/subscriber_serializer.rb +13 -0
  143. data/app/serializers/spree/api/v2/platform/wished_item_serializer.rb +29 -0
  144. data/app/serializers/spree/api/v2/platform/wishlist_serializer.rb +19 -0
  145. data/app/serializers/spree/api/v2/platform/zone_member_serializer.rb +13 -0
  146. data/app/serializers/spree/api/v2/platform/zone_serializer.rb +13 -0
  147. data/app/serializers/spree/v2/storefront/address_serializer.rb +1 -1
  148. data/app/serializers/spree/v2/storefront/cart_serializer.rb +1 -1
  149. data/app/serializers/spree/v2/storefront/cms_section_serializer.rb +5 -1
  150. data/app/serializers/spree/v2/storefront/credit_card_serializer.rb +1 -1
  151. data/app/serializers/spree/v2/storefront/digital_link_serializer.rb +11 -0
  152. data/app/serializers/spree/v2/storefront/estimated_shipping_rate_serializer.rb +2 -2
  153. data/app/serializers/spree/v2/storefront/line_item_serializer.rb +2 -1
  154. data/app/serializers/spree/v2/storefront/option_type_serializer.rb +1 -1
  155. data/app/serializers/spree/v2/storefront/option_value_serializer.rb +1 -1
  156. data/app/serializers/spree/v2/storefront/payment_method_serializer.rb +1 -1
  157. data/app/serializers/spree/v2/storefront/payment_serializer.rb +1 -1
  158. data/app/serializers/spree/v2/storefront/product_serializer.rb +2 -2
  159. data/app/serializers/spree/v2/storefront/promotion_serializer.rb +1 -1
  160. data/app/serializers/spree/v2/storefront/shipment_serializer.rb +2 -1
  161. data/app/serializers/spree/v2/storefront/store_credit_serializer.rb +1 -1
  162. data/app/serializers/spree/v2/storefront/store_serializer.rb +1 -1
  163. data/app/serializers/spree/v2/storefront/taxon_serializer.rb +1 -1
  164. data/app/serializers/spree/v2/storefront/taxonomy_serializer.rb +1 -1
  165. data/app/serializers/spree/v2/storefront/user_serializer.rb +1 -1
  166. data/app/serializers/spree/v2/storefront/variant_serializer.rb +1 -1
  167. data/app/serializers/spree/v2/storefront/wished_item_serializer.rb +29 -0
  168. data/app/serializers/spree/v2/storefront/wishlist_serializer.rb +17 -0
  169. data/app/services/spree/webhooks/subscribers/handle_request.rb +73 -0
  170. data/app/services/spree/webhooks/subscribers/make_request.rb +82 -0
  171. data/app/services/spree/webhooks/subscribers/queue_requests.rb +17 -0
  172. data/app/services/spree/webhooks.rb +13 -0
  173. data/config/i18n-tasks.yml +40 -0
  174. data/config/initializers/doorkeeper.rb +12 -12
  175. data/config/initializers/rabl.rb +2 -2
  176. data/config/locales/en.yml +29 -27
  177. data/config/routes.rb +83 -59
  178. data/db/migrate/20210902162826_create_spree_webhooks_tables.rb +16 -0
  179. data/db/migrate/20210919183228_enable_polymorphic_resource_owner.rb +21 -0
  180. data/db/migrate/20211025162826_create_spree_webhooks_events.rb +14 -0
  181. data/docs/oauth/index.yml +126 -33
  182. data/docs/v2/platform/index.yaml +19099 -1736
  183. data/docs/v2/storefront/index.yaml +14801 -14628
  184. data/{app/models/spree → lib/spree/api}/api_dependencies.rb +56 -4
  185. data/lib/spree/api/engine.rb +19 -3
  186. data/lib/spree/api/testing_support/factories/oauth_application_factory.rb +6 -0
  187. data/lib/spree/api/testing_support/factories/webhook_event_factory.rb +27 -0
  188. data/lib/spree/api/testing_support/factories/webhook_subscriber_factory.rb +13 -0
  189. data/lib/spree/api/testing_support/factories.rb +3 -0
  190. data/lib/spree/api/testing_support/helpers.rb +1 -1
  191. data/lib/spree/api/testing_support/jobs.rb +18 -0
  192. data/lib/spree/api/testing_support/matchers/webhooks.rb +67 -0
  193. data/lib/spree/api/testing_support/serializers.rb +25 -0
  194. data/lib/spree/api/testing_support/spree_webhooks.rb +9 -0
  195. data/lib/spree/api/testing_support/v2/base.rb +1 -1
  196. data/lib/spree/api/testing_support/v2/current_order.rb +34 -1
  197. data/lib/spree/api/testing_support/v2/platform_contexts.rb +101 -52
  198. data/lib/spree/api/testing_support/v2/serializers_params.rb +3 -1
  199. data/lib/spree/api.rb +1 -0
  200. data/spec/fixtures/files/icon_256x256.jpg +0 -0
  201. data/spree_api.gemspec +16 -15
  202. metadata +175 -28
  203. data/app/controllers/spree/api/errors_controller.rb +0 -9
@@ -0,0 +1,43 @@
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)
@@ -0,0 +1,26 @@
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)
@@ -0,0 +1,27 @@
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 product.out_of_stock]
8
+ end
9
+
10
+ base.after_update_commit :queue_webhooks_requests_for_product_discontinued!
11
+ end
12
+
13
+ private
14
+
15
+ def queue_webhooks_requests_for_product_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!('product.discontinued')
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ Spree::Product.prepend(Spree::Api::Webhooks::ProductDecorator)
27
+
@@ -0,0 +1,21 @@
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)
@@ -0,0 +1,43 @@
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)
@@ -0,0 +1,52 @@
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)
@@ -0,0 +1,26 @@
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)
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ class OauthAccessGrant < Base
3
+ include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant
4
+
5
+ self.table_name = 'spree_oauth_access_grants'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ class OauthAccessToken < Base
3
+ include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken
4
+
5
+ self.table_name = 'spree_oauth_access_tokens'
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ class OauthApplication < Base
3
+ include ::Doorkeeper::Orm::ActiveRecord::Mixins::Application
4
+
5
+ self.table_name = 'spree_oauth_applications'
6
+
7
+ before_validation :set_blank_for_redirect_uri
8
+
9
+ private
10
+
11
+ def set_blank_for_redirect_uri
12
+ self.redirect_uri = '' if redirect_uri.nil?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module Webhooks
3
+ def self.table_name_prefix
4
+ 'spree_webhooks_'
5
+ end
6
+
7
+ class Base < Spree::Base
8
+ self.abstract_class = true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module Webhooks
3
+ class Event < Spree::Webhooks::Base
4
+ validates :name, :subscriber, presence: true
5
+
6
+ belongs_to :subscriber, inverse_of: :events, optional: false
7
+
8
+ self.whitelisted_ransackable_associations = %w[subscriber]
9
+ self.whitelisted_ransackable_attributes = %w[name request_errors response_code success url]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,57 @@
1
+ module Spree
2
+ module Webhooks
3
+ class Subscriber < Spree::Webhooks::Base
4
+ has_many :events, inverse_of: :subscriber
5
+
6
+ validates :url, 'spree/url': true, presence: true
7
+
8
+ validate :check_uri_path
9
+
10
+ self.whitelisted_ransackable_attributes = %w[active subscriptions url]
11
+ self.whitelisted_ransackable_associations = %w[event]
12
+
13
+ scope :active, -> { where(active: true) }
14
+ scope :inactive, -> { where(active: false) }
15
+
16
+ before_save :parse_subscriptions
17
+
18
+ def self.with_urls_for(event)
19
+ where(
20
+ case ActiveRecord::Base.connection.adapter_name
21
+ when 'Mysql2'
22
+ ["('*' MEMBER OF(subscriptions) OR ? MEMBER OF(subscriptions))", event]
23
+ when 'PostgreSQL'
24
+ ["subscriptions @> '[\"*\"]' OR subscriptions @> ?", [event].to_json]
25
+ end
26
+ )
27
+ end
28
+
29
+ def self.supported_events
30
+ Spree::Base.descendants.
31
+ select { |model| model.included_modules.include? Spree::Webhooks::HasWebhooks }.
32
+ to_h do |model|
33
+ model_name = model.name.demodulize.underscore.to_sym
34
+ [model_name, model.supported_webhook_events]
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def check_uri_path
41
+ uri = begin
42
+ URI.parse(url)
43
+ rescue URI::InvalidURIError
44
+ return false
45
+ end
46
+
47
+ errors.add(:url, 'the URL must have a path') if uri.blank? || uri.path.blank?
48
+ end
49
+
50
+ def parse_subscriptions
51
+ return if subscriptions.blank? || subscriptions.is_a?(Array)
52
+
53
+ self.subscriptions = JSON.parse(subscriptions)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -5,10 +5,28 @@ module Spree
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  def self.included(base)
8
- model_klazz = "Spree::#{base.to_s.demodulize.gsub(/Serializer/, '')}".constantize
8
+ serializer_base_name = base.to_s.sub(/^Spree::Api::V2::Platform::/, '').sub(/Serializer$/, '')
9
+ model_klazz = "Spree::#{serializer_base_name}".constantize
9
10
 
10
11
  base.set_type model_klazz.json_api_type
12
+ # include standard attributes
11
13
  base.attributes(*model_klazz.json_api_columns)
14
+ # include money attributes
15
+ display_getter_methods(model_klazz).each do |method_name|
16
+ base.attribute(method_name) do |object|
17
+ object.public_send(method_name).to_s
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.display_getter_methods(model_klazz)
23
+ model_klazz.new.methods.find_all do |method_name|
24
+ next unless method_name.to_s.start_with?('display_')
25
+ next if method_name.to_s.end_with?('=')
26
+ next if [Spree::Product, Spree::Variant].include?(model_klazz) && method_name == :display_amount
27
+
28
+ method_name
29
+ end
12
30
  end
13
31
  end
14
32
  end
@@ -13,12 +13,19 @@ module Spree
13
13
  opts = options.dup
14
14
 
15
15
  params_cache_key = params.map do |param|
16
- next if param.nil? || param.last.nil?
16
+ value = param.last
17
+ next if param.nil? || value.nil?
17
18
 
18
- if param.last.respond_to?(:cache_key_with_version)
19
- param.last.cache_key_with_version
19
+ if value.respond_to?(:cache_key_with_version)
20
+ value.cache_key_with_version
21
+ elsif value.is_a?(Hash)
22
+ # covers the current_price_options cases:
23
+ # { price_options: { tax_zone: Spree::Zone... } } or
24
+ # { price_options: { tax_zone: nil } }
25
+ only_key = value.keys.first
26
+ value[only_key]&.cache_key_with_version
20
27
  else
21
- param.last.to_s.downcase
28
+ value.to_s.downcase
22
29
  end
23
30
  end.compact.reject(&:blank?).join('-')
24
31
 
@@ -3,7 +3,7 @@ module Spree
3
3
  module V2
4
4
  module Platform
5
5
  class AddressSerializer < BaseSerializer
6
- include ::Spree::Api::V2::ResourceSerializerConcern
6
+ include ResourceSerializerConcern
7
7
 
8
8
  belongs_to :country
9
9
  belongs_to :state
@@ -0,0 +1,20 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class AdjustmentSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+
8
+ belongs_to :order
9
+ belongs_to :adjustable, polymorphic: true
10
+ belongs_to :source, polymorphic: {
11
+ Spree::Promotion::Actions::FreeShipping => :promotion_action,
12
+ Spree::Promotion::Actions::CreateAdjustment => :promotion_action,
13
+ Spree::Promotion::Actions::CreateItemAdjustments => :promotion_action,
14
+ Spree::Promotion::Actions::CreateLineItems => :promotion_action
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class AssetSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+
8
+ belongs_to :viewable, polymorphic: true
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class CalculatorSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+
8
+ attributes :type
9
+
10
+ attribute :preferences do |calculator|
11
+ calculator.preferences
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,7 +3,7 @@ module Spree
3
3
  module V2
4
4
  module Platform
5
5
  class ClassificationSerializer < BaseSerializer
6
- include ::Spree::Api::V2::ResourceSerializerConcern
6
+ include ResourceSerializerConcern
7
7
 
8
8
  belongs_to :product
9
9
  belongs_to :taxon
@@ -3,7 +3,7 @@ module Spree
3
3
  module V2
4
4
  module Platform
5
5
  class CmsPageSerializer < BaseSerializer
6
- include ::Spree::Api::V2::ResourceSerializerConcern
6
+ include ResourceSerializerConcern
7
7
 
8
8
  has_many :cms_sections, serializer: :cms_section
9
9
  end
@@ -3,7 +3,14 @@ module Spree
3
3
  module V2
4
4
  module Platform
5
5
  class CmsSectionSerializer < BaseSerializer
6
- include ::Spree::Api::V2::ResourceSerializerConcern
6
+ include ResourceSerializerConcern
7
+
8
+ belongs_to :cms_page, serializer: :cms_page
9
+ belongs_to :linked_resource, polymorphic: {
10
+ Spree::Cms::Pages::StandardPage => :cms_page,
11
+ Spree::Cms::Pages::FeaturePage => :cms_page,
12
+ Spree::Cms::Pages::Homepage => :cms_page
13
+ }
7
14
  end
8
15
  end
9
16
  end
@@ -3,7 +3,7 @@ module Spree
3
3
  module V2
4
4
  module Platform
5
5
  class CountrySerializer < BaseSerializer
6
- include ::Spree::Api::V2::ResourceSerializerConcern
6
+ include ResourceSerializerConcern
7
7
 
8
8
  has_many :states
9
9
  end
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class CreditCardSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+
8
+ belongs_to :payment_method
9
+ belongs_to :user
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class CustomerReturnSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+
8
+ belongs_to :stock_location
9
+
10
+ has_many :reimbursements
11
+ has_many :return_items
12
+ has_many :return_authorizations
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class DigitalLinkSerializer < BaseSerializer
6
+ set_type :digital_link
7
+
8
+ attributes :token, :access_counter
9
+
10
+ belongs_to :digital
11
+ belongs_to :line_item
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class DigitalSerializer < BaseSerializer
6
+ set_type :digital
7
+
8
+ attribute :url do |digital|
9
+ url_helpers = Rails.application.routes.url_helpers
10
+ url_helpers.polymorphic_url(digital.attachment, only_path: true)
11
+ end
12
+
13
+ attribute :content_type do |digital|
14
+ digital.attachment.content_type.to_s
15
+ end
16
+
17
+ attribute :filename do |digital|
18
+ digital.attachment.filename.to_s
19
+ end
20
+
21
+ attribute :byte_size do |digital|
22
+ digital.attachment.byte_size.to_i
23
+ end
24
+
25
+ belongs_to :variant
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class FeaturePageSerializer < CmsPageSerializer
6
+ # Place holder serializer for Webhooks.
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class HomepageSerializer < CmsPageSerializer
6
+ # Place holder serializer for Webhooks.
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class InventoryUnitSerializer < BaseSerializer
6
+ include ResourceSerializerConcern
7
+
8
+ belongs_to :order
9
+ belongs_to :variant
10
+ belongs_to :shipment
11
+ has_many :return_items
12
+ has_many :return_authorizations
13
+ belongs_to :line_item
14
+ belongs_to :original_return_item, serializer: :return_item, type: :return_item
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end