spree_api 5.4.4 → 5.5.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/Rakefile +19 -0
- data/app/controllers/concerns/spree/api/v3/admin/auth_cookies.rb +62 -0
- data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +149 -0
- data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +54 -0
- data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +103 -0
- data/app/controllers/concerns/spree/api/v3/channel_resolution.rb +60 -0
- data/app/controllers/concerns/spree/api/v3/error_handler.rb +4 -0
- data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +84 -0
- data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +88 -0
- data/app/controllers/concerns/spree/api/v3/store/search_provider_support.rb +35 -1
- data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +97 -0
- data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +55 -0
- data/app/controllers/spree/api/v3/admin/auth_controller.rb +134 -0
- data/app/controllers/spree/api/v3/admin/base_controller.rb +3 -17
- data/app/controllers/spree/api/v3/admin/categories_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/channels_controller.rb +65 -0
- data/app/controllers/spree/api/v3/admin/countries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/admin/coupon_codes_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +34 -0
- data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +108 -0
- data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +88 -0
- data/app/controllers/spree/api/v3/admin/customers/credit_cards_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/customers_controller.rb +119 -0
- data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +44 -0
- data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/exports_controller.rb +89 -0
- data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +138 -0
- data/app/controllers/spree/api/v3/admin/invitations_controller.rb +70 -0
- data/app/controllers/spree/api/v3/admin/markets_controller.rb +42 -0
- data/app/controllers/spree/api/v3/admin/me_controller.rb +69 -0
- data/app/controllers/spree/api/v3/admin/media_controller.rb +119 -0
- data/app/controllers/spree/api/v3/admin/option_types_controller.rb +34 -0
- data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/orders/base_controller.rb +26 -0
- data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +104 -0
- data/app/controllers/spree/api/v3/admin/orders/gift_cards_controller.rb +79 -0
- data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +92 -0
- data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +90 -0
- data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +53 -0
- data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +59 -0
- data/app/controllers/spree/api/v3/admin/orders_controller.rb +190 -0
- data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +73 -0
- data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +156 -0
- data/app/controllers/spree/api/v3/admin/prices_controller.rb +129 -0
- data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +48 -0
- data/app/controllers/spree/api/v3/admin/products_controller.rb +237 -0
- data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +78 -0
- data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/promotions_controller.rb +78 -0
- data/app/controllers/spree/api/v3/admin/resource_controller.rb +29 -11
- data/app/controllers/spree/api/v3/admin/roles_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +35 -0
- data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +36 -0
- data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/store_controller.rb +53 -0
- data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +21 -0
- data/app/controllers/spree/api/v3/admin/tags_controller.rb +51 -0
- data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +21 -0
- data/app/controllers/spree/api/v3/admin/variants_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/webhook_deliveries_controller.rb +49 -0
- data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +75 -0
- data/app/controllers/spree/api/v3/resource_controller.rb +90 -8
- data/app/controllers/spree/api/v3/store/auth_controller.rb +8 -28
- data/app/controllers/spree/api/v3/store/base_controller.rb +6 -0
- data/app/controllers/spree/api/v3/store/carts_controller.rb +3 -15
- data/app/controllers/spree/api/v3/store/customers_controller.rb +6 -0
- data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +77 -0
- data/app/controllers/spree/api/v3/store/products/filters_controller.rb +2 -2
- data/app/controllers/spree/api/v3/store/products_controller.rb +3 -3
- data/app/controllers/spree/api/v3/store/resource_controller.rb +10 -2
- data/app/jobs/spree/webhook_delivery_job.rb +6 -6
- data/app/models/spree/api_key_ability.rb +16 -0
- data/app/serializers/spree/api/v3/admin/address_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +3 -15
- data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +19 -3
- data/app/serializers/spree/api/v3/admin/allowed_origin_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +42 -0
- data/app/serializers/spree/api/v3/admin/category_serializer.rb +4 -3
- data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/country_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/coupon_code_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +4 -2
- data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +8 -3
- data/app/serializers/spree/api/v3/admin/customer_group_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/admin/customer_serializer.rb +58 -2
- data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +143 -0
- data/app/serializers/spree/api/v3/admin/export_serializer.rb +40 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/{asset_serializer.rb → gift_card_batch_serializer.rb} +1 -1
- data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +39 -4
- data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +64 -0
- data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +4 -16
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +24 -2
- data/app/serializers/spree/api/v3/admin/option_type_serializer.rb +4 -1
- data/app/serializers/spree/api/v3/admin/option_value_serializer.rb +4 -1
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +21 -6
- data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +11 -2
- data/app/serializers/spree/api/v3/admin/payment_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/payment_source_serializer.rb +4 -1
- data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +51 -0
- data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +55 -0
- data/app/serializers/spree/api/v3/admin/price_serializer.rb +4 -0
- data/app/serializers/spree/api/v3/admin/product_publication_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +34 -10
- data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +71 -0
- data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +85 -0
- data/app/serializers/spree/api/v3/admin/promotion_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/admin/refund_serializer.rb +4 -2
- data/app/serializers/spree/api/v3/admin/role_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +16 -1
- data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +11 -2
- data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +19 -0
- data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +11 -5
- data/app/serializers/spree/api/v3/admin/store_serializer.rb +55 -0
- data/app/serializers/spree/api/v3/admin/tax_category_serializer.rb +4 -2
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +37 -6
- data/app/serializers/spree/api/v3/admin/webhook_delivery_serializer.rb +1 -6
- data/app/serializers/spree/api/v3/admin/webhook_endpoint_serializer.rb +69 -0
- data/app/serializers/spree/api/v3/channel_serializer.rb +14 -0
- data/app/serializers/spree/api/v3/custom_field_serializer.rb +9 -10
- data/app/serializers/spree/api/v3/customer_serializer.rb +5 -0
- data/app/serializers/spree/api/v3/market_serializer.rb +2 -1
- data/app/serializers/spree/api/v3/media_serializer.rb +8 -6
- data/app/serializers/spree/api/v3/order_serializer.rb +6 -1
- data/app/serializers/spree/api/v3/payment_method_serializer.rb +11 -2
- data/app/serializers/spree/api/v3/product_publication_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/product_serializer.rb +6 -1
- data/app/serializers/spree/api/v3/stock_reservation_serializer.rb +10 -0
- data/app/services/spree/webhooks/deliver_webhook.rb +2 -6
- data/app/subscribers/spree/webhook_event_subscriber.rb +2 -5
- data/config/locales/en.yml +2 -0
- data/config/routes.rb +235 -1
- data/lib/spree/api/configuration.rb +2 -2
- data/lib/spree/api/dependencies.rb +25 -1
- data/lib/spree/api/openapi/path_sorter.rb +126 -0
- data/lib/spree/api/openapi/schema_helper.rb +185 -6
- metadata +95 -8
- data/app/serializers/spree/api/v3/admin/shipping_category_serializer.rb +0 -14
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StockReservationSerializer < V3::StockReservationSerializer
|
|
6
|
+
typelize stock_item_id: :string,
|
|
7
|
+
line_item_id: :string,
|
|
8
|
+
order_id: :string,
|
|
9
|
+
variant_id: [:string, nullable: true],
|
|
10
|
+
stock_location_id: [:string, nullable: true],
|
|
11
|
+
quantity: :number,
|
|
12
|
+
expires_at: :string,
|
|
13
|
+
active: :boolean
|
|
14
|
+
|
|
15
|
+
attribute :stock_item_id do |reservation|
|
|
16
|
+
reservation.stock_item.prefixed_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attribute :line_item_id do |reservation|
|
|
20
|
+
reservation.line_item.prefixed_id
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attribute :order_id do |reservation|
|
|
24
|
+
reservation.order.prefixed_id
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attribute :variant_id do |reservation|
|
|
28
|
+
reservation.stock_item&.variant&.prefixed_id
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
attribute :stock_location_id do |reservation|
|
|
32
|
+
reservation.stock_item&.stock_location&.prefixed_id
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
attributes :quantity, expires_at: :iso8601
|
|
36
|
+
|
|
37
|
+
attribute :active do |reservation|
|
|
38
|
+
reservation.active?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
attributes created_at: :iso8601, updated_at: :iso8601
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Inventory movement between two stock locations (or external →
|
|
6
|
+
# location for receives). The originating location is `nil` for
|
|
7
|
+
# receives (vendor stock arriving) and present for transfers.
|
|
8
|
+
class StockTransferSerializer < V3::BaseSerializer
|
|
9
|
+
typelize number: :string,
|
|
10
|
+
reference: [:string, nullable: true],
|
|
11
|
+
source_location_id: [:string, nullable: true],
|
|
12
|
+
destination_location_id: [:string, nullable: true],
|
|
13
|
+
metadata: 'Record<string, unknown>'
|
|
14
|
+
|
|
15
|
+
attributes :number, :reference, :metadata,
|
|
16
|
+
created_at: :iso8601, updated_at: :iso8601
|
|
17
|
+
|
|
18
|
+
attribute :source_location_id do |stock_transfer|
|
|
19
|
+
stock_transfer.source_location&.prefixed_id
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
attribute :destination_location_id do |stock_transfer|
|
|
23
|
+
stock_transfer.destination_location&.prefixed_id
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
one :source_location,
|
|
27
|
+
resource: Spree.api.admin_stock_location_serializer,
|
|
28
|
+
if: proc { expand?('source_location') }
|
|
29
|
+
|
|
30
|
+
one :destination_location,
|
|
31
|
+
resource: Spree.api.admin_stock_location_serializer,
|
|
32
|
+
if: proc { expand?('destination_location') }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StoreCreditCategorySerializer < V3::BaseSerializer
|
|
6
|
+
typelize name: :string,
|
|
7
|
+
non_expiring: :boolean
|
|
8
|
+
|
|
9
|
+
attributes :name,
|
|
10
|
+
created_at: :iso8601, updated_at: :iso8601
|
|
11
|
+
|
|
12
|
+
attribute :non_expiring do |store_credit_category|
|
|
13
|
+
store_credit_category.non_expiring?
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -5,9 +5,13 @@ module Spree
|
|
|
5
5
|
class StoreCreditSerializer < V3::StoreCreditSerializer
|
|
6
6
|
typelize customer_id: [:string, nullable: true],
|
|
7
7
|
created_by_id: [:string, nullable: true],
|
|
8
|
-
|
|
8
|
+
category_id: [:string, nullable: true],
|
|
9
|
+
category_name: [:string, nullable: true],
|
|
10
|
+
memo: [:string, nullable: true],
|
|
11
|
+
metadata: 'Record<string, unknown>'
|
|
9
12
|
|
|
10
|
-
attributes
|
|
13
|
+
attributes :memo, :metadata,
|
|
14
|
+
created_at: :iso8601, updated_at: :iso8601
|
|
11
15
|
|
|
12
16
|
attribute :customer_id do |store_credit|
|
|
13
17
|
store_credit.user&.prefixed_id
|
|
@@ -17,11 +21,13 @@ module Spree
|
|
|
17
21
|
store_credit.created_by&.prefixed_id
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
attribute :
|
|
21
|
-
store_credit.
|
|
24
|
+
attribute :category_id do |store_credit|
|
|
25
|
+
store_credit.category&.prefixed_id
|
|
22
26
|
end
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
attribute :category_name do |store_credit|
|
|
29
|
+
store_credit.category_name
|
|
30
|
+
end
|
|
25
31
|
end
|
|
26
32
|
end
|
|
27
33
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StoreSerializer < V3::BaseSerializer
|
|
6
|
+
typelize name: :string, url: :string,
|
|
7
|
+
default_currency: :string, default_locale: :string,
|
|
8
|
+
supported_currencies: [:string, multi: true],
|
|
9
|
+
supported_locales: [:string, multi: true],
|
|
10
|
+
logo_url: [:string, nullable: true],
|
|
11
|
+
mailer_logo_url: [:string, nullable: true],
|
|
12
|
+
mail_from_address: [:string, nullable: true],
|
|
13
|
+
customer_support_email: [:string, nullable: true],
|
|
14
|
+
new_order_notifications_email: [:string, nullable: true],
|
|
15
|
+
preferred_send_consumer_transactional_emails: :boolean,
|
|
16
|
+
preferred_admin_locale: [:string, nullable: true],
|
|
17
|
+
preferred_timezone: :string,
|
|
18
|
+
preferred_weight_unit: :string,
|
|
19
|
+
preferred_unit_system: :string,
|
|
20
|
+
metadata: 'Record<string, unknown>'
|
|
21
|
+
|
|
22
|
+
attributes :metadata,
|
|
23
|
+
:name,
|
|
24
|
+
:default_currency,
|
|
25
|
+
:default_locale,
|
|
26
|
+
:mail_from_address,
|
|
27
|
+
:customer_support_email,
|
|
28
|
+
:new_order_notifications_email,
|
|
29
|
+
:preferred_send_consumer_transactional_emails,
|
|
30
|
+
:preferred_admin_locale,
|
|
31
|
+
:preferred_timezone,
|
|
32
|
+
:preferred_weight_unit,
|
|
33
|
+
:preferred_unit_system,
|
|
34
|
+
created_at: :iso8601, updated_at: :iso8601
|
|
35
|
+
|
|
36
|
+
attribute :url, &:storefront_url
|
|
37
|
+
|
|
38
|
+
attribute :supported_currencies do |store|
|
|
39
|
+
store.supported_currencies_list.map(&:iso_code)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
attribute :supported_locales, &:supported_locales_list
|
|
43
|
+
|
|
44
|
+
attribute :logo_url do |store|
|
|
45
|
+
image_url_for(store.logo)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
attribute :mailer_logo_url do |store|
|
|
49
|
+
image_url_for(store.mailer_logo)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -3,10 +3,12 @@ module Spree
|
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
5
|
class TaxCategorySerializer < V3::BaseSerializer
|
|
6
|
-
typelize name: :string,
|
|
6
|
+
typelize name: :string,
|
|
7
|
+
tax_code: [:string, nullable: true],
|
|
8
|
+
description: [:string, nullable: true],
|
|
7
9
|
is_default: :boolean
|
|
8
10
|
|
|
9
|
-
attributes :name, :tax_code, :is_default,
|
|
11
|
+
attributes :name, :tax_code, :description, :is_default,
|
|
10
12
|
created_at: :iso8601, updated_at: :iso8601
|
|
11
13
|
end
|
|
12
14
|
end
|
|
@@ -6,16 +6,43 @@ module Spree
|
|
|
6
6
|
# Full variant data including admin-only fields
|
|
7
7
|
class VariantSerializer < V3::VariantSerializer
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
typelize product_name: :string,
|
|
10
|
+
position: :number, tax_category_id: [:string, nullable: true],
|
|
11
11
|
cost_price: [:string, nullable: true], cost_currency: [:string, nullable: true],
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
barcode: [:string, nullable: true],
|
|
13
|
+
weight_unit: [:string, nullable: true], dimensions_unit: [:string, nullable: true],
|
|
14
|
+
available_stock: [:number, nullable: true],
|
|
15
|
+
reserved_quantity: :number, total_on_hand: [:number, nullable: true],
|
|
16
|
+
deleted_at: [:string, nullable: true],
|
|
17
|
+
metadata: 'Record<string, unknown>'
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
attributes :metadata, :position, :cost_price, :cost_currency,
|
|
20
|
+
:barcode, :weight_unit, :dimensions_unit, deleted_at: :iso8601,
|
|
17
21
|
created_at: :iso8601, updated_at: :iso8601
|
|
18
22
|
|
|
23
|
+
attribute :tax_category_id do |variant|
|
|
24
|
+
variant.tax_category&.prefixed_id
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Physical pool minus already-allocated units. In 5.5 allocated_count
|
|
28
|
+
# is always 0, so this equals SUM(stock_items.count_on_hand).
|
|
29
|
+
attribute :available_stock do |variant|
|
|
30
|
+
variant.available_stock.to_i if variant.should_track_inventory?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
attribute :reserved_quantity do |variant|
|
|
34
|
+
variant.reserved_quantity.to_i
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Purchasable now: available_stock minus active reservations.
|
|
38
|
+
attribute :total_on_hand do |variant|
|
|
39
|
+
variant.total_on_hand.to_i if variant.should_track_inventory?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
attribute :product_name do |variant|
|
|
43
|
+
variant.product&.name
|
|
44
|
+
end
|
|
45
|
+
|
|
19
46
|
# Override inherited associations to use admin serializers
|
|
20
47
|
one :primary_media,
|
|
21
48
|
resource: Spree.api.admin_media_serializer,
|
|
@@ -37,6 +64,10 @@ module Spree
|
|
|
37
64
|
key: :custom_fields,
|
|
38
65
|
resource: Spree.api.admin_custom_field_serializer,
|
|
39
66
|
if: proc { expand?('custom_fields') }
|
|
67
|
+
|
|
68
|
+
many :stock_items,
|
|
69
|
+
resource: Spree.api.admin_stock_item_serializer,
|
|
70
|
+
if: proc { expand?('stock_items') }
|
|
40
71
|
end
|
|
41
72
|
end
|
|
42
73
|
end
|
|
@@ -25,15 +25,10 @@ module Spree
|
|
|
25
25
|
|
|
26
26
|
attributes :event_name, :event_id, :response_code, :execution_time,
|
|
27
27
|
:error_type, :request_errors, :response_body, :success,
|
|
28
|
+
:payload,
|
|
28
29
|
created_at: :iso8601, updated_at: :iso8601,
|
|
29
30
|
delivered_at: :iso8601
|
|
30
31
|
|
|
31
|
-
# Redacted again on read: deliveries written before payload redaction
|
|
32
|
-
# shipped still hold live credentials in the column.
|
|
33
|
-
attribute :payload do |delivery|
|
|
34
|
-
Spree::WebhookPayloadRedaction.split(delivery.payload).first
|
|
35
|
-
end
|
|
36
|
-
|
|
37
32
|
attribute :webhook_endpoint_id do |delivery|
|
|
38
33
|
delivery.webhook_endpoint&.prefixed_id
|
|
39
34
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Api
|
|
5
|
+
module V3
|
|
6
|
+
module Admin
|
|
7
|
+
# Admin API serializer for {Spree::WebhookEndpoint}.
|
|
8
|
+
#
|
|
9
|
+
# Never exposes `secret_key` outside of the create response (encrypted
|
|
10
|
+
# at rest, plaintext only in memory after generation). The full secret
|
|
11
|
+
# is delivered exactly once via {#secret_key} below — `nil` everywhere
|
|
12
|
+
# else.
|
|
13
|
+
class WebhookEndpointSerializer < V3::BaseSerializer
|
|
14
|
+
typelize name: [:string, nullable: true],
|
|
15
|
+
url: :string,
|
|
16
|
+
active: :boolean,
|
|
17
|
+
subscriptions: [:string, multi: true],
|
|
18
|
+
secret_key: [:string, nullable: true],
|
|
19
|
+
disabled_at: [:string, nullable: true],
|
|
20
|
+
disabled_reason: [:string, nullable: true],
|
|
21
|
+
last_delivery_at: [:string, nullable: true],
|
|
22
|
+
recent_delivery_count: :number,
|
|
23
|
+
recent_failure_count: :number,
|
|
24
|
+
total_delivery_count: :number,
|
|
25
|
+
successful_delivery_count: :number,
|
|
26
|
+
failed_delivery_count: :number
|
|
27
|
+
|
|
28
|
+
attributes :name, :url, :active, :subscriptions,
|
|
29
|
+
:disabled_reason,
|
|
30
|
+
created_at: :iso8601, updated_at: :iso8601,
|
|
31
|
+
disabled_at: :iso8601
|
|
32
|
+
|
|
33
|
+
# Plaintext on the create response only — the model owns the
|
|
34
|
+
# "fresh-from-create" rule via `secret_key_for_response`. Every
|
|
35
|
+
# subsequent read serializes nil.
|
|
36
|
+
attribute :secret_key, &:secret_key_for_response
|
|
37
|
+
|
|
38
|
+
attribute :last_delivery_at do |endpoint|
|
|
39
|
+
value = endpoint.webhook_deliveries.maximum(:delivered_at)
|
|
40
|
+
value.respond_to?(:iso8601) ? value.iso8601 : value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
attribute :recent_delivery_count do |endpoint|
|
|
44
|
+
endpoint.webhook_deliveries.where(created_at: 7.days.ago..).count
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attribute :recent_failure_count do |endpoint|
|
|
48
|
+
endpoint.webhook_deliveries.where(created_at: 7.days.ago.., success: false).count
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Lifetime totals — back the health summary panel on the endpoint
|
|
52
|
+
# detail sheet (success % over all deliveries, like the legacy admin's
|
|
53
|
+
# `_summary.html.erb`).
|
|
54
|
+
attribute :total_delivery_count do |endpoint|
|
|
55
|
+
endpoint.webhook_deliveries.count
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
attribute :successful_delivery_count do |endpoint|
|
|
59
|
+
endpoint.webhook_deliveries.successful.count
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
attribute :failed_delivery_count do |endpoint|
|
|
63
|
+
endpoint.webhook_deliveries.failed.count
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -2,19 +2,18 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
# Store API Custom Field Serializer
|
|
5
|
-
# Customer-facing custom field data (
|
|
5
|
+
# Customer-facing custom field data (storefront-visible only)
|
|
6
6
|
class CustomFieldSerializer < BaseSerializer
|
|
7
|
-
typelize key: :string,
|
|
7
|
+
typelize key: :string,
|
|
8
|
+
label: :string,
|
|
9
|
+
type: [:string, deprecated: 'Use `field_type` instead. The legacy `type` field returns the Ruby STI class name (e.g. `Spree::Metafields::ShortText`) and will be removed in a future minor.'],
|
|
10
|
+
field_type: Spree::Metafield::FIELD_TYPE_TOKENS,
|
|
11
|
+
value: :any
|
|
8
12
|
|
|
9
|
-
attributes :label, :type
|
|
13
|
+
attributes :label, :type, :field_type
|
|
10
14
|
|
|
11
|
-
attribute :key
|
|
12
|
-
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
attribute :value do |metafield|
|
|
16
|
-
metafield.serialize_value
|
|
17
|
-
end
|
|
15
|
+
attribute :key, &:full_key
|
|
16
|
+
attribute :value, &:serialize_value
|
|
18
17
|
end
|
|
19
18
|
end
|
|
20
19
|
end
|
|
@@ -5,12 +5,17 @@ module Spree
|
|
|
5
5
|
# Customer-facing user data
|
|
6
6
|
class CustomerSerializer < BaseSerializer
|
|
7
7
|
typelize email: :string, first_name: [:string, nullable: true], last_name: [:string, nullable: true],
|
|
8
|
+
full_name: :string,
|
|
8
9
|
phone: [:string, nullable: true], accepts_email_marketing: :boolean,
|
|
9
10
|
available_store_credit_total: :string, display_available_store_credit_total: :string,
|
|
10
11
|
default_billing_address: { nullable: true }, default_shipping_address: { nullable: true }
|
|
11
12
|
|
|
12
13
|
attributes :email, :first_name, :last_name, :phone, :accepts_email_marketing
|
|
13
14
|
|
|
15
|
+
attribute :full_name do |user|
|
|
16
|
+
user.full_name.presence || user.email
|
|
17
|
+
end
|
|
18
|
+
|
|
14
19
|
attribute :available_store_credit_total do |user, params|
|
|
15
20
|
store = params&.dig(:store) || Spree::Current.store
|
|
16
21
|
currency = params&.dig(:currency) || Spree::Current.currency || store&.default_currency
|
|
@@ -5,10 +5,11 @@ module Spree
|
|
|
5
5
|
typelize name: :string, currency: :string,
|
|
6
6
|
default_locale: :string,
|
|
7
7
|
supported_locales: [:string, multi: true],
|
|
8
|
+
country_isos: [:string, multi: true],
|
|
8
9
|
tax_inclusive: :boolean,
|
|
9
10
|
default: :boolean
|
|
10
11
|
|
|
11
|
-
attributes :name, :currency, :default_locale, :tax_inclusive, :default
|
|
12
|
+
attributes :name, :currency, :default_locale, :tax_inclusive, :default, :country_isos
|
|
12
13
|
|
|
13
14
|
attribute :supported_locales do |market|
|
|
14
15
|
market.supported_locales_list
|
|
@@ -19,13 +19,15 @@ module Spree
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# Returns prefixed IDs of variants this media is associated with.
|
|
22
|
-
#
|
|
22
|
+
# Two paths coexist in 5.5:
|
|
23
|
+
# - legacy: asset.viewable IS the variant (direct upload, viewable_type 'Spree::Variant')
|
|
24
|
+
# - new: asset.variants — product-level asset linked via VariantMedia rows
|
|
25
|
+
# Both are reported so the admin can show a unified "assigned variants" list.
|
|
23
26
|
attribute :variant_ids do |asset|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
27
|
+
ids = []
|
|
28
|
+
ids << asset.viewable&.prefixed_id if asset.viewable_type == 'Spree::Variant' && asset.viewable
|
|
29
|
+
ids.concat(asset.variants.map(&:prefixed_id)) if asset.viewable_type == 'Spree::Product'
|
|
30
|
+
ids.compact.uniq
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
attributes :position, :alt, :media_type,
|
|
@@ -5,7 +5,8 @@ module Spree
|
|
|
5
5
|
# Post-purchase order data (completed orders)
|
|
6
6
|
class OrderSerializer < BaseSerializer
|
|
7
7
|
typelize number: :string, email: :string,
|
|
8
|
-
customer_note: [:string, nullable: true],
|
|
8
|
+
customer_note: [:string, nullable: true],
|
|
9
|
+
market_id: [:string, nullable: true], channel_id: [:string, nullable: true],
|
|
9
10
|
currency: :string, locale: [:string, nullable: true], total_quantity: :number,
|
|
10
11
|
fulfillment_status: [:string, nullable: true], payment_status: [:string, nullable: true],
|
|
11
12
|
item_total: :string, display_item_total: :string,
|
|
@@ -28,6 +29,10 @@ module Spree
|
|
|
28
29
|
order.market&.prefixed_id
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
attribute :channel_id do |order|
|
|
33
|
+
order.channel&.prefixed_id
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
attributes :number, :email, :customer_note,
|
|
32
37
|
:currency, :locale, :total_quantity,
|
|
33
38
|
:item_total, :display_item_total,
|
|
@@ -2,13 +2,22 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
class PaymentMethodSerializer < BaseSerializer
|
|
5
|
-
typelize name: :string, description: [:string, nullable: true], type: :string,
|
|
5
|
+
typelize name: :string, description: [:string, nullable: true], type: :string,
|
|
6
|
+
session_required: :boolean, source_required: :boolean
|
|
6
7
|
|
|
7
|
-
attributes :name, :description
|
|
8
|
+
attributes :name, :description
|
|
9
|
+
|
|
10
|
+
attribute :type do |payment_method|
|
|
11
|
+
payment_method.class.api_type
|
|
12
|
+
end
|
|
8
13
|
|
|
9
14
|
attribute :session_required do |payment_method|
|
|
10
15
|
payment_method.session_required?
|
|
11
16
|
end
|
|
17
|
+
|
|
18
|
+
attribute :source_required do |payment_method|
|
|
19
|
+
payment_method.source_required?
|
|
20
|
+
end
|
|
12
21
|
end
|
|
13
22
|
end
|
|
14
23
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
class ProductPublicationSerializer < BaseSerializer
|
|
5
|
+
typelize product_id: :string,
|
|
6
|
+
channel_id: :string,
|
|
7
|
+
published_at: [:string, nullable: true],
|
|
8
|
+
unpublished_at: [:string, nullable: true]
|
|
9
|
+
|
|
10
|
+
attributes published_at: :iso8601, unpublished_at: :iso8601
|
|
11
|
+
|
|
12
|
+
attribute :product_id do |publication|
|
|
13
|
+
publication.product&.prefixed_id
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attribute :channel_id do |publication|
|
|
17
|
+
publication.channel&.prefixed_id
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -5,6 +5,7 @@ module Spree
|
|
|
5
5
|
# Customer-facing product data with limited fields
|
|
6
6
|
class ProductSerializer < BaseSerializer
|
|
7
7
|
typelize name: :string, description: [:string, nullable: true], description_html: [:string, nullable: true], slug: :string,
|
|
8
|
+
meta_title: [:string, nullable: true],
|
|
8
9
|
meta_description: [:string, nullable: true], meta_keywords: [:string, nullable: true],
|
|
9
10
|
variant_count: :number,
|
|
10
11
|
default_variant_id: :string,
|
|
@@ -16,7 +17,7 @@ module Spree
|
|
|
16
17
|
tags: [:string, multi: true]
|
|
17
18
|
|
|
18
19
|
attributes :name, :slug,
|
|
19
|
-
:meta_description, :meta_keywords,
|
|
20
|
+
:meta_title, :meta_description, :meta_keywords,
|
|
20
21
|
:variant_count,
|
|
21
22
|
available_on: :iso8601
|
|
22
23
|
|
|
@@ -99,6 +100,10 @@ module Spree
|
|
|
99
100
|
resource: Spree.api.option_type_serializer,
|
|
100
101
|
if: proc { expand?('option_types') }
|
|
101
102
|
|
|
103
|
+
many :option_values,
|
|
104
|
+
resource: Spree.api.option_value_serializer,
|
|
105
|
+
if: proc { expand?('option_values') }
|
|
106
|
+
|
|
102
107
|
many :taxons,
|
|
103
108
|
proc { |taxons, params|
|
|
104
109
|
taxons.select { |t| t.taxonomy.store_id == params[:store].id }
|
|
@@ -56,7 +56,7 @@ module Spree
|
|
|
56
56
|
'X-Spree-Webhook-Timestamp' => webhook_timestamp.to_s,
|
|
57
57
|
'X-Spree-Webhook-Event' => @delivery.event_name
|
|
58
58
|
}
|
|
59
|
-
body =
|
|
59
|
+
body = @delivery.payload.to_json
|
|
60
60
|
http_options = { open_timeout: TIMEOUT, read_timeout: TIMEOUT, verify_mode: ssl_verify_mode }
|
|
61
61
|
|
|
62
62
|
# SSRF protection is disabled in development so webhooks can reach
|
|
@@ -77,14 +77,10 @@ module Spree
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def generate_signature
|
|
80
|
+
payload_json = @delivery.payload.to_json
|
|
80
81
|
OpenSSL::HMAC.hexdigest('SHA256', @secret_key, "#{webhook_timestamp}.#{payload_json}")
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
# Memoized so the signature is computed over exactly the bytes sent.
|
|
84
|
-
def payload_json
|
|
85
|
-
@payload_json ||= @delivery.deliverable_payload.to_json
|
|
86
|
-
end
|
|
87
|
-
|
|
88
84
|
def webhook_timestamp
|
|
89
85
|
@webhook_timestamp ||= Time.current.to_i
|
|
90
86
|
end
|
|
@@ -50,16 +50,13 @@ module Spree
|
|
|
50
50
|
)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
# Live credentials go over the wire but never into the delivery log.
|
|
54
|
-
persisted_payload, secrets = Spree::WebhookPayloadRedaction.split(payload)
|
|
55
|
-
|
|
56
53
|
delivery = endpoint.webhook_deliveries.create!(
|
|
57
54
|
event_name: event.name,
|
|
58
55
|
event_id: event.id,
|
|
59
|
-
payload:
|
|
56
|
+
payload: payload
|
|
60
57
|
)
|
|
61
58
|
|
|
62
|
-
Spree::WebhookDeliveryJob.perform_later(delivery.id
|
|
59
|
+
Spree::WebhookDeliveryJob.perform_later(delivery.id)
|
|
63
60
|
rescue ActiveRecord::RecordNotUnique
|
|
64
61
|
# Race condition: another thread already created this delivery — safe to ignore
|
|
65
62
|
rescue StandardError => e
|
data/config/locales/en.yml
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
en:
|
|
3
3
|
spree:
|
|
4
4
|
api:
|
|
5
|
+
cannot_delete: "%{model} cannot be deleted"
|
|
5
6
|
current_password_invalid: Current password is invalid or missing
|
|
6
7
|
gateway_error: 'There was a problem with the payment gateway: %{text}'
|
|
7
8
|
invalid_api_key: Invalid API key (%{key}) specified.
|
|
@@ -9,6 +10,7 @@ en:
|
|
|
9
10
|
invalid_taxonomy_id: Invalid taxonomy id.
|
|
10
11
|
must_specify_api_key: You must specify an API key.
|
|
11
12
|
negative_quantity: quantity is negative
|
|
13
|
+
newsletter_verification_token_invalid: Newsletter verification token is invalid or has expired.
|
|
12
14
|
order:
|
|
13
15
|
could_not_transition: The order could not be transitioned. Please fix the errors and try again.
|
|
14
16
|
insufficient_quantity: An item in your cart has become unavailable.
|