spree_api 5.5.2 → 5.6.0.rc1
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/v3/admin/role_grant_guard.rb +3 -1
- data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +1 -1
- data/app/controllers/concerns/spree/api/v3/channel_resolution.rb +4 -2
- data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +4 -1
- data/app/controllers/concerns/spree/api/v3/storefront_gating.rb +65 -0
- data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +98 -0
- data/app/controllers/spree/api/v3/admin/categories_controller.rb +102 -2
- data/app/controllers/spree/api/v3/admin/customers_controller.rb +8 -2
- data/app/controllers/spree/api/v3/admin/exports_controller.rb +3 -1
- data/app/controllers/spree/api/v3/admin/import_rows_controller.rb +49 -0
- data/app/controllers/spree/api/v3/admin/imports_controller.rb +274 -0
- data/app/controllers/spree/api/v3/admin/locales_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/me_controller.rb +39 -9
- data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +62 -2
- data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +105 -0
- data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +1 -8
- data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/products_controller.rb +8 -7
- data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/resource_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/store_controller.rb +3 -0
- data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +38 -0
- data/app/controllers/spree/api/v3/admin/translations/batches_controller.rb +113 -0
- data/app/controllers/spree/api/v3/admin/translations_controller.rb +106 -0
- data/app/controllers/spree/api/v3/resource_controller.rb +0 -2
- data/app/controllers/spree/api/v3/store/auth_controller.rb +3 -1
- data/app/controllers/spree/api/v3/store/base_controller.rb +5 -0
- data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +1 -3
- data/app/controllers/spree/api/v3/store/carts_controller.rb +4 -0
- data/app/controllers/spree/api/v3/store/countries_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/currencies_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +5 -1
- data/app/controllers/spree/api/v3/store/customers_controller.rb +3 -1
- data/app/controllers/spree/api/v3/store/digitals_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/locales_controller.rb +3 -8
- data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/markets_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/products/filters_controller.rb +12 -8
- data/app/controllers/spree/api/v3/store/products_controller.rb +1 -1
- data/app/controllers/spree/api/v3/store/resource_controller.rb +1 -0
- data/app/serializers/concerns/spree/api/v3/admin/translatable.rb +38 -0
- data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +7 -1
- data/app/serializers/spree/api/v3/admin/category_serializer.rb +5 -3
- data/app/serializers/spree/api/v3/admin/channel_serializer.rb +5 -1
- data/app/serializers/spree/api/v3/admin/customer_serializer.rb +7 -2
- data/app/serializers/spree/api/v3/admin/discount_serializer.rb +4 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +9 -0
- data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +7 -0
- data/app/serializers/spree/api/v3/admin/import_mapping_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/admin/import_row_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/admin/import_serializer.rb +70 -0
- data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/option_type_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +15 -1
- data/app/serializers/spree/api/v3/admin/payment_serializer.rb +4 -0
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +1 -0
- data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +8 -0
- data/app/serializers/spree/api/v3/admin/resource_translations_serializer.rb +76 -0
- data/app/serializers/spree/api/v3/admin/setup_task_serializer.rb +18 -0
- data/app/serializers/spree/api/v3/admin/store_serializer.rb +27 -1
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +8 -1
- data/app/serializers/spree/api/v3/base_serializer.rb +13 -0
- data/app/serializers/spree/api/v3/cart_serializer.rb +25 -22
- data/app/serializers/spree/api/v3/discount_serializer.rb +6 -2
- data/app/serializers/spree/api/v3/fulfillment_serializer.rb +16 -13
- data/app/serializers/spree/api/v3/gift_card_serializer.rb +15 -11
- data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/line_item_serializer.rb +35 -17
- data/app/serializers/spree/api/v3/locale_serializer.rb +6 -1
- data/app/serializers/spree/api/v3/order_serializer.rb +25 -21
- data/app/serializers/spree/api/v3/payment_serializer.rb +6 -2
- data/app/serializers/spree/api/v3/product_filter_availability_option_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/product_filter_availability_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/product_filter_category_option_serializer.rb +14 -0
- data/app/serializers/spree/api/v3/product_filter_category_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +18 -0
- data/app/serializers/spree/api/v3/product_filter_option_value_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/product_filter_price_range_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/product_filter_sort_option_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/product_filters_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/product_serializer.rb +9 -1
- data/app/serializers/spree/api/v3/variant_serializer.rb +12 -1
- data/app/services/spree/api/v3/filters_aggregator.rb +4 -4
- data/app/subscribers/spree/webhook_event_subscriber.rb +6 -0
- data/config/initializers/typelizer.rb +10 -0
- data/config/locales/en.yml +4 -0
- data/config/routes.rb +54 -4
- data/lib/spree/api/dependencies.rb +14 -0
- data/lib/spree/api/openapi/schema_helper.rb +29 -0
- metadata +30 -6
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
module V3
|
|
6
6
|
class ImportRowSerializer < BaseSerializer
|
|
7
7
|
typelize import_id: [:string, nullable: true], row_number: :number,
|
|
8
|
-
status: :string, validation_errors:
|
|
8
|
+
status: :string, validation_errors: [:string, nullable: true],
|
|
9
9
|
item_type: [:string, nullable: true], item_id: [:string, nullable: true]
|
|
10
10
|
|
|
11
11
|
attributes :row_number, :status, :validation_errors, :item_type,
|
|
@@ -4,32 +4,50 @@ module Spree
|
|
|
4
4
|
class LineItemSerializer < BaseSerializer
|
|
5
5
|
typelize variant_id: :string, quantity: :number, currency: :string,
|
|
6
6
|
name: :string, slug: :string, options_text: :string,
|
|
7
|
-
price: :string,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
price: [:string, nullable: true], display_price: [:string, nullable: true],
|
|
8
|
+
total: [:string, nullable: true], display_total: [:string, nullable: true],
|
|
9
|
+
adjustment_total: [:string, nullable: true], display_adjustment_total: [:string, nullable: true],
|
|
10
|
+
additional_tax_total: [:string, nullable: true], display_additional_tax_total: [:string, nullable: true],
|
|
11
|
+
included_tax_total: [:string, nullable: true], display_included_tax_total: [:string, nullable: true],
|
|
12
|
+
discount_total: [:string, nullable: true], display_discount_total: [:string, nullable: true],
|
|
13
|
+
pre_tax_amount: [:string, nullable: true], display_pre_tax_amount: [:string, nullable: true],
|
|
14
|
+
discounted_amount: [:string, nullable: true], display_discounted_amount: [:string, nullable: true],
|
|
14
15
|
compare_at_amount: [:string, nullable: true], display_compare_at_amount: [:string, nullable: true],
|
|
15
|
-
thumbnail_url: [:string, nullable: true]
|
|
16
|
+
thumbnail_url: [:string, nullable: true],
|
|
17
|
+
preorder: :boolean, preorder_ships_at: [:string, nullable: true]
|
|
16
18
|
|
|
17
19
|
attribute :variant_id do |line_item|
|
|
18
20
|
line_item.variant&.prefixed_id
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
# True when the line item's variant is currently a pre-order, so the
|
|
24
|
+
# cart/checkout can flag it as shipping later.
|
|
25
|
+
attribute :preorder do |line_item|
|
|
26
|
+
line_item.variant&.preorder? || false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The variant's "ships by" promise while it's a pre-order.
|
|
30
|
+
attribute :preorder_ships_at do |line_item|
|
|
31
|
+
line_item.variant&.preorder_ships_at&.iso8601 if line_item.variant&.preorder?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
attributes :quantity, :currency, :name, :slug, :options_text
|
|
35
|
+
|
|
36
|
+
# Nulled for gated (prices_hidden) guests so the cart's line items can't
|
|
37
|
+
# leak the prices that product/variant serializers already withhold.
|
|
38
|
+
money_attributes :price, :display_price, :total, :display_total,
|
|
39
|
+
:adjustment_total, :display_adjustment_total,
|
|
40
|
+
:additional_tax_total, :display_additional_tax_total,
|
|
41
|
+
:included_tax_total, :display_included_tax_total,
|
|
42
|
+
:discount_total, :display_discount_total,
|
|
43
|
+
:pre_tax_amount, :display_pre_tax_amount,
|
|
44
|
+
:discounted_amount, :display_discounted_amount,
|
|
45
|
+
:display_compare_at_amount
|
|
30
46
|
|
|
31
47
|
# Return compare_at_amount as string, nil if zero
|
|
32
48
|
attribute :compare_at_amount do |line_item|
|
|
49
|
+
next nil if params[:hide_prices]
|
|
50
|
+
|
|
33
51
|
amount = line_item.compare_at_amount
|
|
34
52
|
amount.present? && amount.positive? ? amount.to_s : nil
|
|
35
53
|
end
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
|
+
# Serializes a Spree::Locale. The display name, default flag, and RTL
|
|
5
|
+
# direction all live on the model — this is a thin projection of it.
|
|
4
6
|
class LocaleSerializer
|
|
5
7
|
include Alba::Resource
|
|
6
8
|
include Typelizer::DSL
|
|
7
9
|
|
|
8
|
-
typelize code: :string, name: :string
|
|
10
|
+
typelize code: :string, name: :string, default: :boolean, rtl: :boolean
|
|
9
11
|
|
|
10
12
|
attributes :code, :name
|
|
13
|
+
|
|
14
|
+
attribute(:default, &:default?)
|
|
15
|
+
attribute(:rtl, &:rtl?)
|
|
11
16
|
end
|
|
12
17
|
end
|
|
13
18
|
end
|
|
@@ -9,18 +9,18 @@ module Spree
|
|
|
9
9
|
market_id: [:string, nullable: true], channel_id: [:string, nullable: true],
|
|
10
10
|
currency: :string, locale: [:string, nullable: true], total_quantity: :number,
|
|
11
11
|
fulfillment_status: [:string, nullable: true], payment_status: [:string, nullable: true],
|
|
12
|
-
item_total: :string, display_item_total: :string,
|
|
13
|
-
delivery_total: :string, display_delivery_total: :string,
|
|
14
|
-
adjustment_total: :string, display_adjustment_total: :string,
|
|
15
|
-
discount_total: :string, display_discount_total: :string,
|
|
16
|
-
tax_total: :string, display_tax_total: :string,
|
|
17
|
-
included_tax_total: :string, display_included_tax_total: :string,
|
|
18
|
-
additional_tax_total: :string, display_additional_tax_total: :string,
|
|
19
|
-
store_credit_total: :string, display_store_credit_total: :string,
|
|
20
|
-
gift_card_total: :string, display_gift_card_total: :string,
|
|
12
|
+
item_total: [:string, nullable: true], display_item_total: [:string, nullable: true],
|
|
13
|
+
delivery_total: [:string, nullable: true], display_delivery_total: [:string, nullable: true],
|
|
14
|
+
adjustment_total: [:string, nullable: true], display_adjustment_total: [:string, nullable: true],
|
|
15
|
+
discount_total: [:string, nullable: true], display_discount_total: [:string, nullable: true],
|
|
16
|
+
tax_total: [:string, nullable: true], display_tax_total: [:string, nullable: true],
|
|
17
|
+
included_tax_total: [:string, nullable: true], display_included_tax_total: [:string, nullable: true],
|
|
18
|
+
additional_tax_total: [:string, nullable: true], display_additional_tax_total: [:string, nullable: true],
|
|
19
|
+
store_credit_total: [:string, nullable: true], display_store_credit_total: [:string, nullable: true],
|
|
20
|
+
gift_card_total: [:string, nullable: true], display_gift_card_total: [:string, nullable: true],
|
|
21
21
|
covered_by_store_credit: :boolean,
|
|
22
|
-
total: :string, display_total: :string,
|
|
23
|
-
amount_due: :string, display_amount_due: :string,
|
|
22
|
+
total: [:string, nullable: true], display_total: [:string, nullable: true],
|
|
23
|
+
amount_due: [:string, nullable: true], display_amount_due: [:string, nullable: true],
|
|
24
24
|
completed_at: [:string, nullable: true],
|
|
25
25
|
billing_address: { nullable: true }, shipping_address: { nullable: true },
|
|
26
26
|
gift_card: { nullable: true }, market: { nullable: true }
|
|
@@ -35,22 +35,26 @@ module Spree
|
|
|
35
35
|
|
|
36
36
|
attributes :number, :email, :customer_note,
|
|
37
37
|
:currency, :locale, :total_quantity,
|
|
38
|
-
:
|
|
39
|
-
:adjustment_total, :display_adjustment_total,
|
|
40
|
-
:discount_total, :display_discount_total,
|
|
41
|
-
:tax_total, :display_tax_total, :included_tax_total, :display_included_tax_total,
|
|
42
|
-
:additional_tax_total, :display_additional_tax_total, :total, :display_total,
|
|
43
|
-
:gift_card_total, :display_gift_card_total,
|
|
44
|
-
:amount_due, :display_amount_due,
|
|
45
|
-
:delivery_total, :display_delivery_total, :fulfillment_status, :payment_status,
|
|
38
|
+
:fulfillment_status, :payment_status,
|
|
46
39
|
completed_at: :iso8601
|
|
47
40
|
|
|
41
|
+
# Nulled for gated (prices_hidden) guests, consistent with cart and
|
|
42
|
+
# catalog price hiding.
|
|
43
|
+
money_attributes :item_total, :display_item_total,
|
|
44
|
+
:adjustment_total, :display_adjustment_total,
|
|
45
|
+
:discount_total, :display_discount_total,
|
|
46
|
+
:tax_total, :display_tax_total, :included_tax_total, :display_included_tax_total,
|
|
47
|
+
:additional_tax_total, :display_additional_tax_total, :total, :display_total,
|
|
48
|
+
:gift_card_total, :display_gift_card_total,
|
|
49
|
+
:amount_due, :display_amount_due,
|
|
50
|
+
:delivery_total, :display_delivery_total
|
|
51
|
+
|
|
48
52
|
attribute :store_credit_total do |order|
|
|
49
|
-
order.total_applied_store_credit.to_s
|
|
53
|
+
order.total_applied_store_credit.to_s unless params[:hide_prices]
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
attribute :display_store_credit_total do |order|
|
|
53
|
-
order.display_total_applied_store_credit.to_s
|
|
57
|
+
order.display_total_applied_store_credit.to_s unless params[:hide_prices]
|
|
54
58
|
end
|
|
55
59
|
|
|
56
60
|
attribute :covered_by_store_credit do |order|
|
|
@@ -3,7 +3,7 @@ module Spree
|
|
|
3
3
|
module V3
|
|
4
4
|
class PaymentSerializer < BaseSerializer
|
|
5
5
|
typelize status: :string, payment_method_id: :string, response_code: [:string, nullable: true],
|
|
6
|
-
number: :string, amount: :string, display_amount: :string,
|
|
6
|
+
number: :string, amount: [:string, nullable: true], display_amount: [:string, nullable: true],
|
|
7
7
|
source_type: [:string, nullable: true, enum: %w[credit_card store_credit payment_source]],
|
|
8
8
|
source_id: [:string, nullable: true],
|
|
9
9
|
source: 'CreditCard | StoreCredit | PaymentSource | null'
|
|
@@ -12,7 +12,11 @@ module Spree
|
|
|
12
12
|
payment.payment_method&.prefixed_id
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
attributes :response_code, :number
|
|
15
|
+
attributes :response_code, :number
|
|
16
|
+
|
|
17
|
+
# Nulled for gated (prices_hidden) guests so a payment can't leak the
|
|
18
|
+
# amount the cart/order totals already withhold.
|
|
19
|
+
money_attributes :amount, :display_amount
|
|
16
20
|
|
|
17
21
|
attribute :status do |payment|
|
|
18
22
|
payment.state
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFilterAvailabilitySerializer < BaseSerializer
|
|
5
|
+
typelize id: :string,
|
|
6
|
+
type: "'availability'",
|
|
7
|
+
options: [:ProductFilterAvailabilityOption, multi: true]
|
|
8
|
+
|
|
9
|
+
attributes :id, :type
|
|
10
|
+
|
|
11
|
+
many :options, resource: proc { Spree.api.product_filter_availability_option_serializer }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFilterCategoryOptionSerializer < BaseSerializer
|
|
5
|
+
typelize id: :string,
|
|
6
|
+
name: :string,
|
|
7
|
+
permalink: :string,
|
|
8
|
+
count: :number
|
|
9
|
+
|
|
10
|
+
attributes :id, :name, :permalink, :count
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFilterCategorySerializer < BaseSerializer
|
|
5
|
+
typelize id: :string,
|
|
6
|
+
type: "'category'",
|
|
7
|
+
options: [:ProductFilterCategoryOption, multi: true]
|
|
8
|
+
|
|
9
|
+
attributes :id, :type
|
|
10
|
+
|
|
11
|
+
many :options, resource: proc { Spree.api.product_filter_category_option_serializer }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFilterOptionSerializer < BaseSerializer
|
|
5
|
+
typelize id: :string,
|
|
6
|
+
type: "'option'",
|
|
7
|
+
name: :string,
|
|
8
|
+
label: :string,
|
|
9
|
+
kind: :string,
|
|
10
|
+
options: [:ProductFilterOptionValue, multi: true]
|
|
11
|
+
|
|
12
|
+
attributes :id, :type, :name, :label, :kind
|
|
13
|
+
|
|
14
|
+
many :options, resource: proc { Spree.api.product_filter_option_value_serializer }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFilterOptionValueSerializer < BaseSerializer
|
|
5
|
+
typelize id: :string,
|
|
6
|
+
name: :string,
|
|
7
|
+
label: :string,
|
|
8
|
+
position: :number,
|
|
9
|
+
color_code: [:string, nullable: true],
|
|
10
|
+
image_url: [:string, nullable: true],
|
|
11
|
+
count: :number
|
|
12
|
+
|
|
13
|
+
attributes :id, :name, :label, :position, :color_code, :image_url, :count
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFilterPriceRangeSerializer < BaseSerializer
|
|
5
|
+
typelize id: :string,
|
|
6
|
+
type: "'price_range'",
|
|
7
|
+
min: :number,
|
|
8
|
+
max: :number,
|
|
9
|
+
currency: :string
|
|
10
|
+
|
|
11
|
+
attributes :id, :type, :min, :max, :currency
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductFiltersSerializer < BaseSerializer
|
|
5
|
+
typelize default_sort: :string,
|
|
6
|
+
total_count: :number,
|
|
7
|
+
filters: 'Array<ProductFilterPriceRange | ProductFilterAvailability | ProductFilterOption | ProductFilterCategory>',
|
|
8
|
+
sort_options: [:ProductFilterSortOption, { multi: true }]
|
|
9
|
+
|
|
10
|
+
attributes :default_sort, :total_count
|
|
11
|
+
|
|
12
|
+
attribute :filters do |result|
|
|
13
|
+
result.filters.filter_map do |filter|
|
|
14
|
+
filter_type = filter[:type]
|
|
15
|
+
serializer_class = case filter_type
|
|
16
|
+
when 'price_range'
|
|
17
|
+
Spree.api.product_filter_price_range_serializer
|
|
18
|
+
when 'availability'
|
|
19
|
+
Spree.api.product_filter_availability_serializer
|
|
20
|
+
when 'option'
|
|
21
|
+
Spree.api.product_filter_option_serializer
|
|
22
|
+
when 'category'
|
|
23
|
+
Spree.api.product_filter_category_serializer
|
|
24
|
+
else
|
|
25
|
+
raise ArgumentError, "Unknown filter type: #{filter_type.inspect}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
serializer_class.new(filter, params: params).serializable_hash
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
many :sort_options, resource: proc { Spree.api.product_filter_sort_option_serializer }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -11,7 +11,9 @@ module Spree
|
|
|
11
11
|
default_variant_id: :string,
|
|
12
12
|
thumbnail_url: [:string, nullable: true],
|
|
13
13
|
available_on: [:string, nullable: true],
|
|
14
|
+
preorder_ships_at: [:string, nullable: true],
|
|
14
15
|
purchasable: :boolean, in_stock: :boolean, backorderable: :boolean, available: :boolean,
|
|
16
|
+
preorder: :boolean,
|
|
15
17
|
price: 'Price',
|
|
16
18
|
original_price: ['Price', nullable: true],
|
|
17
19
|
tags: [:string, multi: true]
|
|
@@ -19,12 +21,18 @@ module Spree
|
|
|
19
21
|
attributes :name, :slug,
|
|
20
22
|
:meta_title, :meta_description, :meta_keywords,
|
|
21
23
|
:variant_count,
|
|
22
|
-
available_on: :iso8601
|
|
24
|
+
available_on: :iso8601, preorder_ships_at: :iso8601
|
|
23
25
|
|
|
24
26
|
attribute :purchasable do |product|
|
|
25
27
|
product.purchasable?
|
|
26
28
|
end
|
|
27
29
|
|
|
30
|
+
# True when this product is currently offered as a pre-order on the
|
|
31
|
+
# requesting channel.
|
|
32
|
+
attribute :preorder do |product|
|
|
33
|
+
product.preorder?
|
|
34
|
+
end
|
|
35
|
+
|
|
28
36
|
attribute :in_stock do |product|
|
|
29
37
|
product.in_stock?
|
|
30
38
|
end
|
|
@@ -7,7 +7,8 @@ module Spree
|
|
|
7
7
|
typelize product_id: :string, sku: [:string, nullable: true],
|
|
8
8
|
options_text: :string, track_inventory: :boolean, media_count: :number,
|
|
9
9
|
thumbnail_url: [:string, nullable: true],
|
|
10
|
-
purchasable: :boolean, in_stock: :boolean, backorderable: :boolean,
|
|
10
|
+
purchasable: :boolean, in_stock: :boolean, backorderable: :boolean, preorder: :boolean,
|
|
11
|
+
preorder_ships_at: [:string, nullable: true],
|
|
11
12
|
weight: [:number, nullable: true], height: [:number, nullable: true], width: [:number, nullable: true], depth: [:number, nullable: true],
|
|
12
13
|
price: 'Price',
|
|
13
14
|
original_price: ['Price', nullable: true]
|
|
@@ -18,6 +19,12 @@ module Spree
|
|
|
18
19
|
|
|
19
20
|
attributes :sku, :options_text, :track_inventory, :media_count
|
|
20
21
|
|
|
22
|
+
# Customer-facing "ships by" promise — only while the variant is a
|
|
23
|
+
# pre-order (nil otherwise, even if a stale date lingers on the column).
|
|
24
|
+
attribute :preorder_ships_at do |variant|
|
|
25
|
+
variant.preorder_ships_at&.iso8601 if variant.preorder?
|
|
26
|
+
end
|
|
27
|
+
|
|
21
28
|
# Main variant image URL for listings (cached primary_media)
|
|
22
29
|
attribute :thumbnail_url do |variant|
|
|
23
30
|
image_url_for(variant.primary_media)
|
|
@@ -35,6 +42,10 @@ module Spree
|
|
|
35
42
|
variant.backorderable?
|
|
36
43
|
end
|
|
37
44
|
|
|
45
|
+
attribute :preorder do |variant|
|
|
46
|
+
variant.preorder?
|
|
47
|
+
end
|
|
48
|
+
|
|
38
49
|
attribute :weight do |variant|
|
|
39
50
|
variant.weight&.to_f
|
|
40
51
|
end
|
|
@@ -87,9 +87,9 @@ module Spree
|
|
|
87
87
|
type_ids = option_types.map(&:id)
|
|
88
88
|
|
|
89
89
|
# Pluck only the columns we need — avoids instantiating thousands of AR models.
|
|
90
|
-
# Force
|
|
90
|
+
# Force the content locale so Mobility returns column values (not translations);
|
|
91
91
|
# translated labels are overlaid separately via load_option_value_translations.
|
|
92
|
-
ov_rows = Mobility.with_locale(
|
|
92
|
+
ov_rows = Mobility.with_locale(Spree::Current.content_locale) do
|
|
93
93
|
Spree::OptionValue
|
|
94
94
|
.where(option_type_id: type_ids)
|
|
95
95
|
.order(:position)
|
|
@@ -144,10 +144,10 @@ module Spree
|
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
# Load translated presentations for option values.
|
|
147
|
-
# Returns { option_value_id => translated_presentation } or empty hash when using the
|
|
147
|
+
# Returns { option_value_id => translated_presentation } or empty hash when using the content locale.
|
|
148
148
|
def load_option_value_translations(ov_ids)
|
|
149
149
|
locale = Spree::Current.locale || I18n.locale.to_s
|
|
150
|
-
return {} if locale.to_s ==
|
|
150
|
+
return {} if locale.to_s == Spree::Current.content_locale
|
|
151
151
|
|
|
152
152
|
Spree::OptionValue::Translation
|
|
153
153
|
.where(spree_option_value_id: ov_ids, locale: locale)
|
|
@@ -17,9 +17,15 @@ module Spree
|
|
|
17
17
|
class WebhookEventSubscriber < Spree::Subscriber
|
|
18
18
|
subscribes_to '*'
|
|
19
19
|
|
|
20
|
+
# Admin auth events carry live credentials (password reset tokens) and have
|
|
21
|
+
# no legitimate external consumer — core delivers those emails itself.
|
|
22
|
+
# Never forward them to webhook endpoints, including '*' subscriptions.
|
|
23
|
+
NON_DELIVERABLE_EVENTS = %w[admin_user.password_reset_requested].freeze
|
|
24
|
+
|
|
20
25
|
def handle(event)
|
|
21
26
|
return unless Spree::Api::Config.webhooks_enabled
|
|
22
27
|
return if event.store_id.blank?
|
|
28
|
+
return if NON_DELIVERABLE_EVENTS.include?(event.name)
|
|
23
29
|
|
|
24
30
|
# Only load the columns we need for matching and delivery
|
|
25
31
|
endpoints = Spree::WebhookEndpoint
|
|
@@ -10,6 +10,16 @@ Rails.application.config.after_initialize do
|
|
|
10
10
|
config.comments = true
|
|
11
11
|
config.listen = false
|
|
12
12
|
|
|
13
|
+
# Teach typelizer's Alba plugin about custom Alba types (see alba.rb);
|
|
14
|
+
# unmapped typed attributes crash generation.
|
|
15
|
+
config.plugin_configs = {
|
|
16
|
+
alba: {
|
|
17
|
+
ts_mapper: Typelizer::SerializerPlugins::Alba::ALBA_TS_MAPPER.merge(
|
|
18
|
+
'iso8601' => { type: :string }
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
# Serializers that exist only for Admin API or events — no Store API controller
|
|
14
24
|
store_excluded = %w[
|
|
15
25
|
Asset CartPromotion OrderPromotion
|
data/config/locales/en.yml
CHANGED
|
@@ -9,6 +9,9 @@ en:
|
|
|
9
9
|
invalid_resource: Invalid resource. Please fix errors and try again.
|
|
10
10
|
invalid_taxonomy_id: Invalid taxonomy id.
|
|
11
11
|
must_specify_api_key: You must specify an API key.
|
|
12
|
+
errors:
|
|
13
|
+
guest_checkout_not_allowed: You must be signed in to complete checkout.
|
|
14
|
+
storefront_login_required: Authentication required to access this store.
|
|
12
15
|
negative_quantity: quantity is negative
|
|
13
16
|
newsletter_verification_token_invalid: Newsletter verification token is invalid or has expired.
|
|
14
17
|
order:
|
|
@@ -20,6 +23,7 @@ en:
|
|
|
20
23
|
payment:
|
|
21
24
|
credit_over_limit: This payment can only be credited up to %{limit}. Please specify an amount less than or equal to this number.
|
|
22
25
|
update_forbidden: This payment cannot be updated because it is %{state}.
|
|
26
|
+
invalid_position: new_position must be an integer
|
|
23
27
|
record_not_found: "%{model} not found"
|
|
24
28
|
redirect_url_not_allowed: The redirect URL is not from an allowed origin for this store.
|
|
25
29
|
resource_not_found: The resource you were looking for could not be found.
|
data/config/routes.rb
CHANGED
|
@@ -103,9 +103,26 @@ Spree::Core::Engine.add_routes do
|
|
|
103
103
|
resources :custom_fields
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
# Mounts a read-only nested `translations` matrix on parents in the
|
|
107
|
+
# Spree.translatable_resources registry. Writes go through the batch
|
|
108
|
+
# endpoint (POST /translations/batch). One generic controller serves
|
|
109
|
+
# every translatable model. See docs/plans/5.5-6.0-resource-translations-api.md.
|
|
110
|
+
concern :translatable do
|
|
111
|
+
resources :translations, only: [:index], controller: 'translations'
|
|
112
|
+
end
|
|
113
|
+
|
|
106
114
|
# Definitions are per resource type, not per instance.
|
|
107
115
|
resources :custom_field_definitions
|
|
108
116
|
|
|
117
|
+
# Translation discovery: the translatable-resources registry and the
|
|
118
|
+
# store's supported locales. See docs/plans/5.5-6.0-resource-translations-api.md.
|
|
119
|
+
resources :translatable_resources, only: [:index]
|
|
120
|
+
resources :locales, only: [:index]
|
|
121
|
+
|
|
122
|
+
# Atomic multi-record translation upsert (e.g. an option type + all its
|
|
123
|
+
# option values in one save). Flat list of independent registry writes.
|
|
124
|
+
post 'translations/batch', to: 'translations/batches#create'
|
|
125
|
+
|
|
109
126
|
# Authentication
|
|
110
127
|
post 'auth/login', to: 'auth#create'
|
|
111
128
|
post 'auth/refresh', to: 'auth#refresh'
|
|
@@ -117,6 +134,12 @@ Spree::Core::Engine.add_routes do
|
|
|
117
134
|
get 'auth/invitations/:id/lookup', to: 'invitation_acceptances#lookup'
|
|
118
135
|
post 'auth/invitations/:id/accept', to: 'invitation_acceptances#accept'
|
|
119
136
|
|
|
137
|
+
# Public password reset — unauthenticated; the token is the credential.
|
|
138
|
+
# Mounted under `auth/` so the refresh-token cookie issued on success
|
|
139
|
+
# shares its path with `/auth/refresh`.
|
|
140
|
+
post 'auth/password_resets', to: 'password_resets#create'
|
|
141
|
+
patch 'auth/password_resets/:id', to: 'password_resets#update'
|
|
142
|
+
|
|
120
143
|
# Dashboard
|
|
121
144
|
namespace :dashboard do
|
|
122
145
|
get :analytics
|
|
@@ -124,6 +147,8 @@ Spree::Core::Engine.add_routes do
|
|
|
124
147
|
|
|
125
148
|
# Current admin user + permissions (for UI permission checks)
|
|
126
149
|
get 'me', to: 'me#show'
|
|
150
|
+
# Self-service profile updates (e.g. the admin's own UI language)
|
|
151
|
+
patch 'me', to: 'me#update'
|
|
127
152
|
|
|
128
153
|
# Store Settings
|
|
129
154
|
resource :store, only: [:show, :update], controller: 'store'
|
|
@@ -168,8 +193,21 @@ Spree::Core::Engine.add_routes do
|
|
|
168
193
|
end
|
|
169
194
|
end
|
|
170
195
|
|
|
196
|
+
# CSV Imports — see docs/plans/5.6-admin-spa-csv-import.md
|
|
197
|
+
resources :imports, only: [:index, :show, :create, :destroy] do
|
|
198
|
+
collection do
|
|
199
|
+
get :template
|
|
200
|
+
end
|
|
201
|
+
member do
|
|
202
|
+
patch :complete_mapping
|
|
203
|
+
patch :retry_failed_rows
|
|
204
|
+
get :download
|
|
205
|
+
end
|
|
206
|
+
resources :rows, only: [:index], controller: 'import_rows'
|
|
207
|
+
end
|
|
208
|
+
|
|
171
209
|
# Products
|
|
172
|
-
resources :products, concerns: :custom_fieldable do
|
|
210
|
+
resources :products, concerns: [:custom_fieldable, :translatable] do
|
|
173
211
|
member do
|
|
174
212
|
post :clone
|
|
175
213
|
end
|
|
@@ -190,10 +228,22 @@ Spree::Core::Engine.add_routes do
|
|
|
190
228
|
end
|
|
191
229
|
|
|
192
230
|
# Categories
|
|
193
|
-
resources :categories,
|
|
231
|
+
resources :categories, concerns: [:custom_fieldable, :translatable] do
|
|
232
|
+
member do
|
|
233
|
+
patch :reposition
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Manual product membership + ordering within the category.
|
|
237
|
+
# (Bulk add/remove reuse POST /products/bulk_{add,remove}_*_categories.)
|
|
238
|
+
resources :products, controller: 'categories/products', only: [:index, :create, :destroy] do
|
|
239
|
+
member do
|
|
240
|
+
patch :reposition
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
194
244
|
|
|
195
245
|
# Option Types (with nested option_values in payload)
|
|
196
|
-
resources :option_types, concerns: :custom_fieldable
|
|
246
|
+
resources :option_types, concerns: [:custom_fieldable, :translatable]
|
|
197
247
|
|
|
198
248
|
# Tax Categories
|
|
199
249
|
resources :tax_categories
|
|
@@ -306,7 +356,7 @@ Spree::Core::Engine.add_routes do
|
|
|
306
356
|
end
|
|
307
357
|
|
|
308
358
|
resources :items, only: [:index, :show, :create, :update, :destroy], controller: 'orders/items'
|
|
309
|
-
resources :fulfillments, controller: 'orders/fulfillments', only: [:index, :show, :update] do
|
|
359
|
+
resources :fulfillments, controller: 'orders/fulfillments', only: [:index, :show, :create, :update] do
|
|
310
360
|
member do
|
|
311
361
|
patch :fulfill
|
|
312
362
|
patch :cancel
|
|
@@ -136,6 +136,15 @@ module Spree
|
|
|
136
136
|
custom_field_serializer: 'Spree::Api::V3::CustomFieldSerializer',
|
|
137
137
|
shipping_category_serializer: 'Spree::Api::V3::ShippingCategorySerializer',
|
|
138
138
|
tax_category_serializer: 'Spree::Api::V3::TaxCategorySerializer',
|
|
139
|
+
product_filters_serializer: 'Spree::Api::V3::ProductFiltersSerializer',
|
|
140
|
+
product_filter_price_range_serializer: 'Spree::Api::V3::ProductFilterPriceRangeSerializer',
|
|
141
|
+
product_filter_availability_serializer: 'Spree::Api::V3::ProductFilterAvailabilitySerializer',
|
|
142
|
+
product_filter_availability_option_serializer: 'Spree::Api::V3::ProductFilterAvailabilityOptionSerializer',
|
|
143
|
+
product_filter_option_serializer: 'Spree::Api::V3::ProductFilterOptionSerializer',
|
|
144
|
+
product_filter_option_value_serializer: 'Spree::Api::V3::ProductFilterOptionValueSerializer',
|
|
145
|
+
product_filter_category_serializer: 'Spree::Api::V3::ProductFilterCategorySerializer',
|
|
146
|
+
product_filter_category_option_serializer: 'Spree::Api::V3::ProductFilterCategoryOptionSerializer',
|
|
147
|
+
product_filter_sort_option_serializer: 'Spree::Api::V3::ProductFilterSortOptionSerializer',
|
|
139
148
|
|
|
140
149
|
# v3 event serializers (for models without Store API endpoints yet)
|
|
141
150
|
asset_serializer: 'Spree::Api::V3::AssetSerializer',
|
|
@@ -207,6 +216,7 @@ module Spree
|
|
|
207
216
|
admin_payment_source_serializer: 'Spree::Api::V3::Admin::PaymentSourceSerializer',
|
|
208
217
|
admin_digital_link_serializer: 'Spree::Api::V3::Admin::DigitalLinkSerializer',
|
|
209
218
|
admin_store_serializer: 'Spree::Api::V3::Admin::StoreSerializer',
|
|
219
|
+
admin_setup_task_serializer: 'Spree::Api::V3::Admin::SetupTaskSerializer',
|
|
210
220
|
admin_api_key_serializer: 'Spree::Api::V3::Admin::ApiKeySerializer',
|
|
211
221
|
admin_allowed_origin_serializer: 'Spree::Api::V3::Admin::AllowedOriginSerializer',
|
|
212
222
|
admin_webhook_endpoint_serializer: 'Spree::Api::V3::Admin::WebhookEndpointSerializer',
|
|
@@ -214,12 +224,16 @@ module Spree
|
|
|
214
224
|
admin_invitation_serializer: 'Spree::Api::V3::Admin::InvitationSerializer',
|
|
215
225
|
admin_role_serializer: 'Spree::Api::V3::Admin::RoleSerializer',
|
|
216
226
|
admin_export_serializer: 'Spree::Api::V3::Admin::ExportSerializer',
|
|
227
|
+
admin_import_serializer: 'Spree::Api::V3::Admin::ImportSerializer',
|
|
228
|
+
admin_import_row_serializer: 'Spree::Api::V3::Admin::ImportRowSerializer',
|
|
229
|
+
admin_import_mapping_serializer: 'Spree::Api::V3::Admin::ImportMappingSerializer',
|
|
217
230
|
admin_promotion_serializer: 'Spree::Api::V3::Admin::PromotionSerializer',
|
|
218
231
|
admin_promotion_action_serializer: 'Spree::Api::V3::Admin::PromotionActionSerializer',
|
|
219
232
|
admin_promotion_rule_serializer: 'Spree::Api::V3::Admin::PromotionRuleSerializer',
|
|
220
233
|
admin_coupon_code_serializer: 'Spree::Api::V3::Admin::CouponCodeSerializer',
|
|
221
234
|
admin_price_list_serializer: 'Spree::Api::V3::Admin::PriceListSerializer',
|
|
222
235
|
admin_price_rule_serializer: 'Spree::Api::V3::Admin::PriceRuleSerializer',
|
|
236
|
+
admin_resource_translations_serializer: 'Spree::Api::V3::Admin::ResourceTranslationsSerializer',
|
|
223
237
|
|
|
224
238
|
# platform serializers
|
|
225
239
|
platform_metafield_serializer: 'Spree::Api::V2::Platform::MetafieldSerializer',
|