spree_api 5.5.3 → 5.6.0.rc2
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 +19 -2
- 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 +69 -1
- data/app/controllers/spree/api/v3/store/products/filters_controller.rb +5 -2
- 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 +17 -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/newsletter_subscriber_serializer.rb +15 -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/customer_serializer.rb +7 -1
- 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_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 +5 -0
- data/config/routes.rb +61 -6
- data/lib/spree/api/dependencies.rb +6 -0
- data/lib/spree/api/openapi/schema_helper.rb +29 -0
- metadata +22 -6
|
@@ -8,7 +8,8 @@ module Spree
|
|
|
8
8
|
full_name: :string,
|
|
9
9
|
phone: [:string, nullable: true], accepts_email_marketing: :boolean,
|
|
10
10
|
available_store_credit_total: :string, display_available_store_credit_total: :string,
|
|
11
|
-
default_billing_address: { nullable: true }, default_shipping_address: { nullable: true }
|
|
11
|
+
default_billing_address: { nullable: true }, default_shipping_address: { nullable: true },
|
|
12
|
+
newsletter_subscriber: { nullable: true }
|
|
12
13
|
|
|
13
14
|
attributes :email, :first_name, :last_name, :phone, :accepts_email_marketing
|
|
14
15
|
|
|
@@ -31,6 +32,11 @@ module Spree
|
|
|
31
32
|
many :addresses, resource: proc { Spree.api.address_serializer }
|
|
32
33
|
one :bill_address, key: :default_billing_address, resource: proc { Spree.api.address_serializer }
|
|
33
34
|
one :ship_address, key: :default_shipping_address, resource: proc { Spree.api.address_serializer }
|
|
35
|
+
|
|
36
|
+
one :newsletter_subscriber, resource: proc { Spree.api.newsletter_subscriber_serializer } do |user, params|
|
|
37
|
+
store = params&.dig(:store) || Spree::Current.store
|
|
38
|
+
user.newsletter_subscriber(store)
|
|
39
|
+
end
|
|
34
40
|
end
|
|
35
41
|
end
|
|
36
42
|
end
|
|
@@ -5,13 +5,17 @@ module Spree
|
|
|
5
5
|
# Replaces CartPromotionSerializer and OrderPromotionSerializer.
|
|
6
6
|
class DiscountSerializer < BaseSerializer
|
|
7
7
|
typelize name: :string, description: [:string, nullable: true], code: [:string, nullable: true],
|
|
8
|
-
amount: :string, display_amount: :string, promotion_id: :string
|
|
8
|
+
amount: [:string, nullable: true], display_amount: [:string, nullable: true], promotion_id: :string
|
|
9
9
|
|
|
10
10
|
attribute :promotion_id do |record|
|
|
11
11
|
record.promotion&.prefixed_id
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
attributes :name, :description, :code
|
|
14
|
+
attributes :name, :description, :code
|
|
15
|
+
|
|
16
|
+
# Nulled for gated (prices_hidden) guests so an applied discount can't
|
|
17
|
+
# leak the amount the cart/order totals already withhold.
|
|
18
|
+
money_attributes :amount, :display_amount
|
|
15
19
|
end
|
|
16
20
|
end
|
|
17
21
|
end
|
|
@@ -5,21 +5,24 @@ module Spree
|
|
|
5
5
|
typelize number: :string, status: :string, fulfillment_type: :string,
|
|
6
6
|
tracking: [:string, nullable: true],
|
|
7
7
|
tracking_url: [:string, nullable: true], fulfilled_at: [:string, nullable: true],
|
|
8
|
-
cost: :string, display_cost: :string,
|
|
9
|
-
total: :string, display_total: :string,
|
|
10
|
-
discount_total: :string, display_discount_total: :string,
|
|
11
|
-
additional_tax_total: :string, display_additional_tax_total: :string,
|
|
12
|
-
included_tax_total: :string, display_included_tax_total: :string,
|
|
13
|
-
tax_total: :string, display_tax_total: :string,
|
|
8
|
+
cost: [:string, nullable: true], display_cost: [:string, nullable: true],
|
|
9
|
+
total: [:string, nullable: true], display_total: [:string, nullable: true],
|
|
10
|
+
discount_total: [:string, nullable: true], display_discount_total: [:string, nullable: true],
|
|
11
|
+
additional_tax_total: [:string, nullable: true], display_additional_tax_total: [:string, nullable: true],
|
|
12
|
+
included_tax_total: [:string, nullable: true], display_included_tax_total: [:string, nullable: true],
|
|
13
|
+
tax_total: [:string, nullable: true], display_tax_total: [:string, nullable: true],
|
|
14
14
|
items: 'Array<{ item_id: string; variant_id: string; quantity: number }>'
|
|
15
15
|
|
|
16
|
-
attributes :number, :tracking, :tracking_url
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
attributes :number, :tracking, :tracking_url
|
|
17
|
+
|
|
18
|
+
# Nulled for gated (prices_hidden) guests so a fulfillment can't leak the
|
|
19
|
+
# shipping/tax amounts the cart/order totals already withhold.
|
|
20
|
+
money_attributes :cost, :display_cost,
|
|
21
|
+
:total, :display_total,
|
|
22
|
+
:discount_total, :display_discount_total,
|
|
23
|
+
:additional_tax_total, :display_additional_tax_total,
|
|
24
|
+
:included_tax_total, :display_included_tax_total,
|
|
25
|
+
:tax_total, :display_tax_total
|
|
23
26
|
|
|
24
27
|
attribute :status do |shipment|
|
|
25
28
|
shipment.state
|
|
@@ -4,13 +4,13 @@ module Spree
|
|
|
4
4
|
class GiftCardSerializer < BaseSerializer
|
|
5
5
|
typelize code: :string,
|
|
6
6
|
status: :string,
|
|
7
|
-
amount: :string,
|
|
8
|
-
amount_used: :string,
|
|
9
|
-
amount_authorized: :string,
|
|
10
|
-
amount_remaining: :string,
|
|
11
|
-
display_amount: :string,
|
|
12
|
-
display_amount_used: :string,
|
|
13
|
-
display_amount_remaining: :string,
|
|
7
|
+
amount: [:string, nullable: true],
|
|
8
|
+
amount_used: [:string, nullable: true],
|
|
9
|
+
amount_authorized: [:string, nullable: true],
|
|
10
|
+
amount_remaining: [:string, nullable: true],
|
|
11
|
+
display_amount: [:string, nullable: true],
|
|
12
|
+
display_amount_used: [:string, nullable: true],
|
|
13
|
+
display_amount_remaining: [:string, nullable: true],
|
|
14
14
|
currency: :string,
|
|
15
15
|
expires_at: [:string, nullable: true],
|
|
16
16
|
redeemed_at: [:string, nullable: true],
|
|
@@ -25,18 +25,22 @@ module Spree
|
|
|
25
25
|
gift_card.display_state
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
attributes :currency
|
|
28
|
+
attributes :currency
|
|
29
|
+
|
|
30
|
+
# Nulled for gated (prices_hidden) guests so a gift card applied to a
|
|
31
|
+
# cart can't leak balances the cart/order totals already withhold.
|
|
32
|
+
money_attributes :amount, :amount_used, :amount_authorized, :amount_remaining
|
|
29
33
|
|
|
30
34
|
attribute :display_amount do |gift_card|
|
|
31
|
-
gift_card.display_amount.to_s
|
|
35
|
+
gift_card.display_amount.to_s unless params[:hide_prices]
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
attribute :display_amount_used do |gift_card|
|
|
35
|
-
gift_card.display_amount_used.to_s
|
|
39
|
+
gift_card.display_amount_used.to_s unless params[:hide_prices]
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
attribute :display_amount_remaining do |gift_card|
|
|
39
|
-
gift_card.display_amount_remaining.to_s
|
|
43
|
+
gift_card.display_amount_remaining.to_s unless params[:hide_prices]
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
attribute :expires_at do |gift_card|
|
|
@@ -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
|
|
@@ -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,7 +9,11 @@ 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
|
|
16
|
+
newsletter_unsubscribe_token_invalid: Newsletter unsubscribe token is invalid or has expired.
|
|
13
17
|
newsletter_verification_token_invalid: Newsletter verification token is invalid or has expired.
|
|
14
18
|
order:
|
|
15
19
|
could_not_transition: The order could not be transitioned. Please fix the errors and try again.
|
|
@@ -20,6 +24,7 @@ en:
|
|
|
20
24
|
payment:
|
|
21
25
|
credit_over_limit: This payment can only be credited up to %{limit}. Please specify an amount less than or equal to this number.
|
|
22
26
|
update_forbidden: This payment cannot be updated because it is %{state}.
|
|
27
|
+
invalid_position: new_position must be an integer
|
|
23
28
|
record_not_found: "%{model} not found"
|
|
24
29
|
redirect_url_not_allowed: The redirect URL is not from an allowed origin for this store.
|
|
25
30
|
resource_not_found: The resource you were looking for could not be found.
|
data/config/routes.rb
CHANGED
|
@@ -59,10 +59,15 @@ Spree::Core::Engine.add_routes do
|
|
|
59
59
|
# Customers
|
|
60
60
|
resources :customers, only: [:create]
|
|
61
61
|
|
|
62
|
-
# Newsletter Subscriptions
|
|
63
|
-
|
|
62
|
+
# Newsletter Subscriptions
|
|
63
|
+
# - create + verify + request_unsubscribe are guest-accessible
|
|
64
|
+
# - destroy accepts either an unsubscribe token (from email links) or JWT auth
|
|
65
|
+
# A signed-in customer reads their own subscription (and its id) off the
|
|
66
|
+
# `newsletter_subscriber` association on GET /customers/me.
|
|
67
|
+
resources :newsletter_subscribers, only: [:create, :destroy] do
|
|
64
68
|
collection do
|
|
65
69
|
post :verify
|
|
70
|
+
post :request_unsubscribe
|
|
66
71
|
end
|
|
67
72
|
end
|
|
68
73
|
|
|
@@ -103,9 +108,26 @@ Spree::Core::Engine.add_routes do
|
|
|
103
108
|
resources :custom_fields
|
|
104
109
|
end
|
|
105
110
|
|
|
111
|
+
# Mounts a read-only nested `translations` matrix on parents in the
|
|
112
|
+
# Spree.translatable_resources registry. Writes go through the batch
|
|
113
|
+
# endpoint (POST /translations/batch). One generic controller serves
|
|
114
|
+
# every translatable model. See docs/plans/5.5-6.0-resource-translations-api.md.
|
|
115
|
+
concern :translatable do
|
|
116
|
+
resources :translations, only: [:index], controller: 'translations'
|
|
117
|
+
end
|
|
118
|
+
|
|
106
119
|
# Definitions are per resource type, not per instance.
|
|
107
120
|
resources :custom_field_definitions
|
|
108
121
|
|
|
122
|
+
# Translation discovery: the translatable-resources registry and the
|
|
123
|
+
# store's supported locales. See docs/plans/5.5-6.0-resource-translations-api.md.
|
|
124
|
+
resources :translatable_resources, only: [:index]
|
|
125
|
+
resources :locales, only: [:index]
|
|
126
|
+
|
|
127
|
+
# Atomic multi-record translation upsert (e.g. an option type + all its
|
|
128
|
+
# option values in one save). Flat list of independent registry writes.
|
|
129
|
+
post 'translations/batch', to: 'translations/batches#create'
|
|
130
|
+
|
|
109
131
|
# Authentication
|
|
110
132
|
post 'auth/login', to: 'auth#create'
|
|
111
133
|
post 'auth/refresh', to: 'auth#refresh'
|
|
@@ -117,6 +139,12 @@ Spree::Core::Engine.add_routes do
|
|
|
117
139
|
get 'auth/invitations/:id/lookup', to: 'invitation_acceptances#lookup'
|
|
118
140
|
post 'auth/invitations/:id/accept', to: 'invitation_acceptances#accept'
|
|
119
141
|
|
|
142
|
+
# Public password reset — unauthenticated; the token is the credential.
|
|
143
|
+
# Mounted under `auth/` so the refresh-token cookie issued on success
|
|
144
|
+
# shares its path with `/auth/refresh`.
|
|
145
|
+
post 'auth/password_resets', to: 'password_resets#create'
|
|
146
|
+
patch 'auth/password_resets/:id', to: 'password_resets#update'
|
|
147
|
+
|
|
120
148
|
# Dashboard
|
|
121
149
|
namespace :dashboard do
|
|
122
150
|
get :analytics
|
|
@@ -124,6 +152,8 @@ Spree::Core::Engine.add_routes do
|
|
|
124
152
|
|
|
125
153
|
# Current admin user + permissions (for UI permission checks)
|
|
126
154
|
get 'me', to: 'me#show'
|
|
155
|
+
# Self-service profile updates (e.g. the admin's own UI language)
|
|
156
|
+
patch 'me', to: 'me#update'
|
|
127
157
|
|
|
128
158
|
# Store Settings
|
|
129
159
|
resource :store, only: [:show, :update], controller: 'store'
|
|
@@ -168,8 +198,21 @@ Spree::Core::Engine.add_routes do
|
|
|
168
198
|
end
|
|
169
199
|
end
|
|
170
200
|
|
|
201
|
+
# CSV Imports — see docs/plans/5.6-admin-spa-csv-import.md
|
|
202
|
+
resources :imports, only: [:index, :show, :create, :destroy] do
|
|
203
|
+
collection do
|
|
204
|
+
get :template
|
|
205
|
+
end
|
|
206
|
+
member do
|
|
207
|
+
patch :complete_mapping
|
|
208
|
+
patch :retry_failed_rows
|
|
209
|
+
get :download
|
|
210
|
+
end
|
|
211
|
+
resources :rows, only: [:index], controller: 'import_rows'
|
|
212
|
+
end
|
|
213
|
+
|
|
171
214
|
# Products
|
|
172
|
-
resources :products, concerns: :custom_fieldable do
|
|
215
|
+
resources :products, concerns: [:custom_fieldable, :translatable] do
|
|
173
216
|
member do
|
|
174
217
|
post :clone
|
|
175
218
|
end
|
|
@@ -190,10 +233,22 @@ Spree::Core::Engine.add_routes do
|
|
|
190
233
|
end
|
|
191
234
|
|
|
192
235
|
# Categories
|
|
193
|
-
resources :categories,
|
|
236
|
+
resources :categories, concerns: [:custom_fieldable, :translatable] do
|
|
237
|
+
member do
|
|
238
|
+
patch :reposition
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Manual product membership + ordering within the category.
|
|
242
|
+
# (Bulk add/remove reuse POST /products/bulk_{add,remove}_*_categories.)
|
|
243
|
+
resources :products, controller: 'categories/products', only: [:index, :create, :destroy] do
|
|
244
|
+
member do
|
|
245
|
+
patch :reposition
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
194
249
|
|
|
195
250
|
# Option Types (with nested option_values in payload)
|
|
196
|
-
resources :option_types, concerns: :custom_fieldable
|
|
251
|
+
resources :option_types, concerns: [:custom_fieldable, :translatable]
|
|
197
252
|
|
|
198
253
|
# Tax Categories
|
|
199
254
|
resources :tax_categories
|
|
@@ -306,7 +361,7 @@ Spree::Core::Engine.add_routes do
|
|
|
306
361
|
end
|
|
307
362
|
|
|
308
363
|
resources :items, only: [:index, :show, :create, :update, :destroy], controller: 'orders/items'
|
|
309
|
-
resources :fulfillments, controller: 'orders/fulfillments', only: [:index, :show, :update] do
|
|
364
|
+
resources :fulfillments, controller: 'orders/fulfillments', only: [:index, :show, :create, :update] do
|
|
310
365
|
member do
|
|
311
366
|
patch :fulfill
|
|
312
367
|
patch :cancel
|
|
@@ -172,6 +172,7 @@ module Spree
|
|
|
172
172
|
admin_state_serializer: 'Spree::Api::V3::Admin::StateSerializer',
|
|
173
173
|
admin_discount_serializer: 'Spree::Api::V3::Admin::DiscountSerializer',
|
|
174
174
|
admin_customer_serializer: 'Spree::Api::V3::Admin::CustomerSerializer',
|
|
175
|
+
admin_newsletter_subscriber_serializer: 'Spree::Api::V3::Admin::NewsletterSubscriberSerializer',
|
|
175
176
|
admin_order_serializer: 'Spree::Api::V3::Admin::OrderSerializer',
|
|
176
177
|
admin_product_serializer: 'Spree::Api::V3::Admin::ProductSerializer',
|
|
177
178
|
admin_variant_serializer: 'Spree::Api::V3::Admin::VariantSerializer',
|
|
@@ -216,6 +217,7 @@ module Spree
|
|
|
216
217
|
admin_payment_source_serializer: 'Spree::Api::V3::Admin::PaymentSourceSerializer',
|
|
217
218
|
admin_digital_link_serializer: 'Spree::Api::V3::Admin::DigitalLinkSerializer',
|
|
218
219
|
admin_store_serializer: 'Spree::Api::V3::Admin::StoreSerializer',
|
|
220
|
+
admin_setup_task_serializer: 'Spree::Api::V3::Admin::SetupTaskSerializer',
|
|
219
221
|
admin_api_key_serializer: 'Spree::Api::V3::Admin::ApiKeySerializer',
|
|
220
222
|
admin_allowed_origin_serializer: 'Spree::Api::V3::Admin::AllowedOriginSerializer',
|
|
221
223
|
admin_webhook_endpoint_serializer: 'Spree::Api::V3::Admin::WebhookEndpointSerializer',
|
|
@@ -223,12 +225,16 @@ module Spree
|
|
|
223
225
|
admin_invitation_serializer: 'Spree::Api::V3::Admin::InvitationSerializer',
|
|
224
226
|
admin_role_serializer: 'Spree::Api::V3::Admin::RoleSerializer',
|
|
225
227
|
admin_export_serializer: 'Spree::Api::V3::Admin::ExportSerializer',
|
|
228
|
+
admin_import_serializer: 'Spree::Api::V3::Admin::ImportSerializer',
|
|
229
|
+
admin_import_row_serializer: 'Spree::Api::V3::Admin::ImportRowSerializer',
|
|
230
|
+
admin_import_mapping_serializer: 'Spree::Api::V3::Admin::ImportMappingSerializer',
|
|
226
231
|
admin_promotion_serializer: 'Spree::Api::V3::Admin::PromotionSerializer',
|
|
227
232
|
admin_promotion_action_serializer: 'Spree::Api::V3::Admin::PromotionActionSerializer',
|
|
228
233
|
admin_promotion_rule_serializer: 'Spree::Api::V3::Admin::PromotionRuleSerializer',
|
|
229
234
|
admin_coupon_code_serializer: 'Spree::Api::V3::Admin::CouponCodeSerializer',
|
|
230
235
|
admin_price_list_serializer: 'Spree::Api::V3::Admin::PriceListSerializer',
|
|
231
236
|
admin_price_rule_serializer: 'Spree::Api::V3::Admin::PriceRuleSerializer',
|
|
237
|
+
admin_resource_translations_serializer: 'Spree::Api::V3::Admin::ResourceTranslationsSerializer',
|
|
232
238
|
|
|
233
239
|
# platform serializers
|
|
234
240
|
platform_metafield_serializer: 'Spree::Api::V2::Platform::MetafieldSerializer',
|