spree_api 5.4.3 → 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 +1 -0
- 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 +5 -0
- 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 +45 -0
- 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/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 +96 -8
- data/app/serializers/spree/api/v3/admin/shipping_category_serializer.rb +0 -14
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# CRUD for `Spree::PromotionRule` STI subclasses. Same shape as
|
|
6
|
+
# PromotionActionsController — only the registry differs
|
|
7
|
+
# (`Spree.promotions.rules` instead of `Spree.promotions.actions`).
|
|
8
|
+
class PromotionRulesController < ResourceController
|
|
9
|
+
include Spree::Api::V3::Admin::SubclassedResource
|
|
10
|
+
|
|
11
|
+
scoped_resource :promotions
|
|
12
|
+
|
|
13
|
+
subclassed_via -> { Spree.promotions.rules },
|
|
14
|
+
unknown_type_error: 'unknown_promotion_rule_type'
|
|
15
|
+
|
|
16
|
+
def types
|
|
17
|
+
authorize! :read, model_class
|
|
18
|
+
|
|
19
|
+
render json: { data: model_class.subclasses_with_preference_schema }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
def model_class
|
|
25
|
+
Spree::PromotionRule
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def serializer_class
|
|
29
|
+
Spree.api.admin_promotion_rule_serializer
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def permitted_params
|
|
33
|
+
params.permit(:type, preferences: {})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def set_parent
|
|
37
|
+
return if action_name == 'types'
|
|
38
|
+
|
|
39
|
+
@parent = Spree::Promotion.accessible_by(current_ability, :show)
|
|
40
|
+
.find_by_prefix_id!(params[:promotion_id])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def parent_association
|
|
44
|
+
:promotion_rules
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def build_subclassed_resource(klass, attrs)
|
|
50
|
+
klass.new(attrs.merge(promotion: @parent))
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class PromotionsController < ResourceController
|
|
6
|
+
scoped_resource :promotions
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def model_class
|
|
11
|
+
Spree::Promotion
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serializer_class
|
|
15
|
+
Spree.api.admin_promotion_serializer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def collection_includes
|
|
19
|
+
promotion_includes
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def scope_includes
|
|
23
|
+
promotion_includes
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# A single POST/PATCH /promotions can ship rules and actions
|
|
27
|
+
# alongside the basics; `Promotion#rules=` / `actions=` reconcile
|
|
28
|
+
# to the desired set. The nested allowlist below is the union of
|
|
29
|
+
# every built-in rule/action's expected keys. Plugin-defined
|
|
30
|
+
# subclasses can add to it — see `additional_permitted_attributes`
|
|
31
|
+
# below.
|
|
32
|
+
def permitted_params
|
|
33
|
+
normalize_params(params.permit(*permitted_attributes))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def permitted_attributes
|
|
37
|
+
[
|
|
38
|
+
:name, :description, :code, :path,
|
|
39
|
+
:starts_at, :expires_at, :usage_limit, :match_policy,
|
|
40
|
+
:kind, :multi_codes, :number_of_codes, :code_prefix,
|
|
41
|
+
:promotion_category_id,
|
|
42
|
+
rules: rule_attributes,
|
|
43
|
+
actions: action_attributes
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def rule_attributes
|
|
48
|
+
[:id, :type, { preferences: {} }, *subclassed_collection_attributes(Spree.promotions.rules)]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def action_attributes
|
|
52
|
+
[
|
|
53
|
+
:id, :type,
|
|
54
|
+
{ preferences: {} },
|
|
55
|
+
{ calculator: [:type, { preferences: {} }] },
|
|
56
|
+
*subclassed_collection_attributes(Spree.promotions.actions)
|
|
57
|
+
]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Pulls in plugin-defined permitted attributes from every
|
|
61
|
+
# registered rule/action subclass. Subclasses declare these via
|
|
62
|
+
# `additional_permitted_attributes` (e.g. `[product_ids: []]`).
|
|
63
|
+
def subclassed_collection_attributes(registry)
|
|
64
|
+
registry.flat_map do |klass|
|
|
65
|
+
klass.respond_to?(:additional_permitted_attributes) ? klass.additional_permitted_attributes : []
|
|
66
|
+
end.uniq
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def promotion_includes
|
|
72
|
+
[:stores, :promotion_actions, :promotion_rules]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -2,24 +2,42 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
|
+
# Mirrors Admin::BaseController's concerns. Both classes anchor parallel
|
|
6
|
+
# inheritance branches (V3::BaseController vs V3::ResourceController);
|
|
7
|
+
# any concern added here MUST also be added to Admin::BaseController.
|
|
5
8
|
class ResourceController < Spree::Api::V3::ResourceController
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Admin API responses must never be cached
|
|
10
|
-
after_action :set_no_store_cache
|
|
9
|
+
include Spree::Api::V3::AdminAuthentication
|
|
10
|
+
include Spree::Api::V3::ScopedAuthorization
|
|
11
11
|
|
|
12
12
|
protected
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
JWT_AUDIENCE_ADMIN
|
|
14
|
+
def authenticate_request!
|
|
15
|
+
authenticate_admin!
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
# Render error from ServiceModule::Result, extracting ActiveModel::Errors
|
|
19
|
+
# from the ResultError wrapper to get proper validation_error responses.
|
|
20
|
+
def render_result_error(result)
|
|
21
|
+
error = result.error
|
|
22
|
+
errors = error.respond_to?(:value) ? error.value : error
|
|
23
|
+
|
|
24
|
+
if errors.is_a?(ActiveModel::Errors)
|
|
25
|
+
render_validation_error(errors)
|
|
26
|
+
else
|
|
27
|
+
render_service_error(error)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def decode_ids(ids, klass)
|
|
32
|
+
Array(ids).map do |id|
|
|
33
|
+
Spree::PrefixedId.prefixed_id?(id) ? klass.find_by_param!(id).id : id
|
|
34
|
+
end
|
|
35
|
+
end
|
|
20
36
|
|
|
21
|
-
def
|
|
22
|
-
|
|
37
|
+
def decode_prefixed_ids(ids)
|
|
38
|
+
Array(ids).map do |id|
|
|
39
|
+
Spree::PrefixedId.prefixed_id?(id) ? Spree::PrefixedId.decode_prefixed_id(id) : id
|
|
40
|
+
end
|
|
23
41
|
end
|
|
24
42
|
end
|
|
25
43
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Read-only list of roles available for staff role pickers (invite +
|
|
6
|
+
# edit forms). Roles are global, not per-store; CRUD is handled
|
|
7
|
+
# outside the SPA today and may grow into a richer permissions UI
|
|
8
|
+
# later. The controller ignores `current_store` for that reason.
|
|
9
|
+
class RolesController < ResourceController
|
|
10
|
+
scoped_resource :settings
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def model_class
|
|
15
|
+
Spree::Role
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def serializer_class
|
|
19
|
+
Spree.api.admin_role_serializer
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def scope
|
|
23
|
+
Spree::Role.accessible_by(current_ability, :show)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Stock items are auto-created when a variant lands at a stock
|
|
6
|
+
# location, so there's deliberately no `create` route — use the
|
|
7
|
+
# variants / stock-locations endpoints for that flow.
|
|
8
|
+
class StockItemsController < ResourceController
|
|
9
|
+
scoped_resource :settings
|
|
10
|
+
|
|
11
|
+
protected
|
|
12
|
+
|
|
13
|
+
def model_class
|
|
14
|
+
Spree::StockItem
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def serializer_class
|
|
18
|
+
Spree.api.admin_stock_item_serializer
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def collection_includes
|
|
22
|
+
[:stock_location, :variant]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# `StockItem.for_store` already applies its own `distinct`, and
|
|
26
|
+
# `id`-asc gives a stable order across edits (variant.position
|
|
27
|
+
# alone isn't unique — see git blame for the row-jumping bug).
|
|
28
|
+
def apply_collection_sort(collection)
|
|
29
|
+
collection.order(Spree::StockItem.arel_table[:id].asc)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StockLocationsController < ResourceController
|
|
6
|
+
scoped_resource :settings
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def model_class
|
|
11
|
+
Spree::StockLocation
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serializer_class
|
|
15
|
+
Spree.api.admin_stock_location_serializer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def scope
|
|
19
|
+
super.order_default
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def permitted_params
|
|
23
|
+
params.permit(
|
|
24
|
+
:name, :admin_name, :active, :default,
|
|
25
|
+
:kind, :propagate_all_variants, :backorderable_default,
|
|
26
|
+
:address1, :address2, :city, :zipcode, :phone, :company,
|
|
27
|
+
:country_iso, :state_abbr, :state_name,
|
|
28
|
+
:pickup_enabled, :pickup_stock_policy,
|
|
29
|
+
:pickup_ready_in_minutes, :pickup_instructions
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StockReservationsController < ResourceController
|
|
6
|
+
scoped_resource :stock
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def model_class
|
|
11
|
+
Spree::StockReservation
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serializer_class
|
|
15
|
+
Spree.api.admin_stock_reservation_serializer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def scope
|
|
19
|
+
Spree::StockReservation.for_store(current_store)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def collection_includes
|
|
23
|
+
[{ stock_item: [:variant, :stock_location], line_item: [], order: [] }]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Inventory movement between stock locations, or vendor → location
|
|
6
|
+
# for receives. Pass `source_location_id` for transfers; omit it to
|
|
7
|
+
# record an external receive.
|
|
8
|
+
class StockTransfersController < ResourceController
|
|
9
|
+
scoped_resource :settings
|
|
10
|
+
|
|
11
|
+
def create
|
|
12
|
+
authorize!(:create, model_class)
|
|
13
|
+
|
|
14
|
+
destination = Spree::StockLocation.find_by_prefix_id!(params[:destination_location_id])
|
|
15
|
+
source = params[:source_location_id].present? ?
|
|
16
|
+
Spree::StockLocation.find_by_prefix_id!(params[:source_location_id]) : nil
|
|
17
|
+
|
|
18
|
+
variants_map = build_variants_map
|
|
19
|
+
if variants_map.empty?
|
|
20
|
+
return render_error(
|
|
21
|
+
code: 'invalid_variants',
|
|
22
|
+
message: Spree.t('stock_transfer.errors.must_have_variant'),
|
|
23
|
+
status: :unprocessable_content
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@resource = source ?
|
|
28
|
+
Spree::StockTransfer.new(reference: params[:reference]).tap { |t| t.transfer(source, destination, variants_map) } :
|
|
29
|
+
Spree::StockTransfer.new(reference: params[:reference]).tap { |t| t.receive(destination, variants_map) }
|
|
30
|
+
|
|
31
|
+
if @resource.persisted?
|
|
32
|
+
render json: serialize_resource(@resource), status: :created
|
|
33
|
+
else
|
|
34
|
+
render_validation_error(@resource.errors)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
|
|
40
|
+
def model_class
|
|
41
|
+
Spree::StockTransfer
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def serializer_class
|
|
45
|
+
Spree.api.admin_stock_transfer_serializer
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def collection_includes
|
|
49
|
+
[:source_location, :destination_location]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# Variants the merchant doesn't have access to are dropped silently;
|
|
55
|
+
# if the resulting map is empty the action surfaces a 422
|
|
56
|
+
# `invalid_variants` so callers can distinguish "nothing supplied"
|
|
57
|
+
# from "all variants were rejected." A single SELECT covers any
|
|
58
|
+
# number of variants instead of N round-trips.
|
|
59
|
+
def build_variants_map
|
|
60
|
+
entries = params.permit(variants: [:variant_id, :quantity]).fetch(:variants, [])
|
|
61
|
+
quantities_by_id = entries.each_with_object({}) do |entry, hash|
|
|
62
|
+
decoded = Spree::PrefixedId.decode_prefixed_id(entry[:variant_id])
|
|
63
|
+
hash[decoded.to_i] = entry[:quantity].to_i if decoded
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
Spree::Variant.where(id: quantities_by_id.keys).each_with_object({}) do |variant, acc|
|
|
67
|
+
quantity = quantities_by_id[variant.id]
|
|
68
|
+
acc[variant] = quantity if quantity&.positive?
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StoreController < Admin::BaseController
|
|
6
|
+
scoped_resource :settings
|
|
7
|
+
|
|
8
|
+
# GET /api/v3/admin/store
|
|
9
|
+
def show
|
|
10
|
+
authorize! :show, current_store
|
|
11
|
+
render json: serialize_store
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# PATCH /api/v3/admin/store
|
|
15
|
+
def update
|
|
16
|
+
authorize! :update, current_store
|
|
17
|
+
|
|
18
|
+
if current_store.update(permitted_params)
|
|
19
|
+
render json: serialize_store
|
|
20
|
+
else
|
|
21
|
+
render_validation_error(current_store.errors)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def serialize_store
|
|
28
|
+
serializer_class.new(current_store, params: serializer_params).to_h
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def serializer_class
|
|
32
|
+
Spree.api.admin_store_serializer
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def permitted_params
|
|
36
|
+
params.permit(
|
|
37
|
+
:name,
|
|
38
|
+
:preferred_admin_locale,
|
|
39
|
+
:preferred_timezone,
|
|
40
|
+
:preferred_weight_unit,
|
|
41
|
+
:preferred_unit_system,
|
|
42
|
+
:mail_from_address,
|
|
43
|
+
:customer_support_email,
|
|
44
|
+
:new_order_notifications_email,
|
|
45
|
+
:preferred_send_consumer_transactional_emails,
|
|
46
|
+
:mailer_logo
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class StoreCreditCategoriesController < ResourceController
|
|
6
|
+
scoped_resource :settings
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def model_class
|
|
11
|
+
Spree::StoreCreditCategory
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serializer_class
|
|
15
|
+
Spree.api.admin_store_credit_category_serializer
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class TagsController < BaseController
|
|
6
|
+
skip_scope_check!
|
|
7
|
+
|
|
8
|
+
MAX_RESULTS = 50
|
|
9
|
+
|
|
10
|
+
def index
|
|
11
|
+
taggable_type = params[:taggable_type].to_s
|
|
12
|
+
unless allowed_taggable_types.include?(taggable_type)
|
|
13
|
+
render_error(
|
|
14
|
+
code: 'invalid_taggable_type',
|
|
15
|
+
message: "taggable_type must be one of #{allowed_taggable_types.join(', ')}",
|
|
16
|
+
status: :unprocessable_content
|
|
17
|
+
)
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
scope = ActsAsTaggableOn::Tag.
|
|
22
|
+
joins(:taggings).
|
|
23
|
+
where(ActsAsTaggableOn.taggings_table => { taggable_type: taggable_type, context: 'tags' }).
|
|
24
|
+
distinct.
|
|
25
|
+
order(:name).
|
|
26
|
+
limit(MAX_RESULTS)
|
|
27
|
+
|
|
28
|
+
if params[:q].present?
|
|
29
|
+
# Escape LIKE wildcards in user input so a query like "foo_" matches
|
|
30
|
+
# only the literal underscore, not any single character.
|
|
31
|
+
escaped = params[:q].to_s.downcase.gsub(/[\\%_]/) { |c| "\\#{c}" }
|
|
32
|
+
scope = scope.where('LOWER(name) LIKE ? ESCAPE ?', "%#{escaped}%", '\\')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
render json: { data: scope.pluck(:name).map { |name| { name: name } } }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# Sourced from `Spree.taggable_types` (registered in
|
|
41
|
+
# `Spree::Core::Engine`'s after_initialize block). Apps extend the
|
|
42
|
+
# list in an initializer without overriding this controller:
|
|
43
|
+
# Spree.taggable_types << 'MyApp::Vendor'
|
|
44
|
+
def allowed_taggable_types
|
|
45
|
+
Spree.taggable_types
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class TaxCategoriesController < ResourceController
|
|
6
|
+
scoped_resource :settings
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def model_class
|
|
11
|
+
Spree::TaxCategory
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serializer_class
|
|
15
|
+
Spree.api.admin_tax_category_serializer
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class VariantsController < ResourceController
|
|
6
|
+
scoped_resource :products
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
def model_class
|
|
11
|
+
Spree::Variant
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serializer_class
|
|
15
|
+
Spree.api.admin_variant_serializer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def scope
|
|
19
|
+
current_store.variants.eligible
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def scope_includes
|
|
23
|
+
[
|
|
24
|
+
:prices, stock_items: :stock_location,
|
|
25
|
+
option_values: :option_type,
|
|
26
|
+
primary_media: [attachment_attachment: :blob]
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Nested under WebhookEndpoint — deliveries are always read in the
|
|
6
|
+
# context of their endpoint (the delivery log on the endpoint detail
|
|
7
|
+
# page) and never accessed by ID at the top level.
|
|
8
|
+
class WebhookDeliveriesController < ResourceController
|
|
9
|
+
scoped_resource :settings
|
|
10
|
+
|
|
11
|
+
# POST /api/v3/admin/webhook_endpoints/:webhook_endpoint_id/deliveries/:id/redeliver
|
|
12
|
+
#
|
|
13
|
+
# Creates a new delivery row with the same payload + event_name and
|
|
14
|
+
# queues it. The original row is preserved for audit history.
|
|
15
|
+
#
|
|
16
|
+
# @return [Hash] the serialized newly-queued {Spree::WebhookDelivery},
|
|
17
|
+
# HTTP 201.
|
|
18
|
+
def redeliver
|
|
19
|
+
@resource = find_resource
|
|
20
|
+
authorize!(:update, webhook_endpoint)
|
|
21
|
+
|
|
22
|
+
new_delivery = @resource.redeliver!
|
|
23
|
+
render json: serialize_resource(new_delivery), status: :created
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
def model_class
|
|
29
|
+
Spree::WebhookDelivery
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def serializer_class
|
|
33
|
+
Spree.api.admin_webhook_delivery_serializer
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def scope
|
|
37
|
+
webhook_endpoint.webhook_deliveries.recent
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def webhook_endpoint
|
|
41
|
+
@webhook_endpoint ||= current_store.webhook_endpoints.find_by_prefix_id!(
|
|
42
|
+
params[:webhook_endpoint_id]
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|