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,79 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module Orders
|
|
6
|
+
class GiftCardsController < BaseController
|
|
7
|
+
scoped_resource :gift_cards
|
|
8
|
+
|
|
9
|
+
skip_before_action :set_resource, raise: false
|
|
10
|
+
|
|
11
|
+
# POST /api/v3/admin/orders/:order_id/gift_cards
|
|
12
|
+
#
|
|
13
|
+
# Body: { code: String }
|
|
14
|
+
def create
|
|
15
|
+
with_order_lock do
|
|
16
|
+
gift_card = find_gift_card!
|
|
17
|
+
return unless gift_card
|
|
18
|
+
|
|
19
|
+
result = @parent.apply_gift_card(gift_card)
|
|
20
|
+
|
|
21
|
+
if result.success?
|
|
22
|
+
render json: serializer_class.new(gift_card).to_h, status: :created
|
|
23
|
+
else
|
|
24
|
+
render_service_error(result.error)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# DELETE /api/v3/admin/orders/:order_id/gift_cards/:id
|
|
30
|
+
def destroy
|
|
31
|
+
with_order_lock do
|
|
32
|
+
result = @parent.remove_gift_card
|
|
33
|
+
|
|
34
|
+
if result.success?
|
|
35
|
+
head :no_content
|
|
36
|
+
else
|
|
37
|
+
render_service_error(result.error)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
protected
|
|
43
|
+
|
|
44
|
+
def model_class
|
|
45
|
+
Spree::GiftCard
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def serializer_class
|
|
49
|
+
Spree.api.admin_gift_card_serializer
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def find_gift_card!
|
|
55
|
+
gift_card = current_store.gift_cards.find_by(code: params[:code]&.downcase)
|
|
56
|
+
|
|
57
|
+
if gift_card.nil?
|
|
58
|
+
render_error(code: ERROR_CODES[:gift_card_not_found], message: Spree.t(:gift_card_not_found), status: :not_found)
|
|
59
|
+
return
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if gift_card.expired?
|
|
63
|
+
render_error(code: ERROR_CODES[:gift_card_expired], message: Spree.t(:gift_card_expired), status: :unprocessable_content)
|
|
64
|
+
return
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if gift_card.redeemed?
|
|
68
|
+
render_error(code: ERROR_CODES[:gift_card_already_redeemed], message: Spree.t(:gift_card_already_redeemed), status: :unprocessable_content)
|
|
69
|
+
return
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
gift_card
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module Orders
|
|
6
|
+
class ItemsController < BaseController
|
|
7
|
+
scoped_resource :orders
|
|
8
|
+
|
|
9
|
+
# POST /api/v3/admin/orders/:order_id/items
|
|
10
|
+
def create
|
|
11
|
+
with_order_lock do
|
|
12
|
+
result = Spree.cart_add_item_service.call(
|
|
13
|
+
order: @parent,
|
|
14
|
+
variant: variant,
|
|
15
|
+
quantity: permitted_params[:quantity] || 1,
|
|
16
|
+
options: permitted_params[:options] || {}
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if result.success?
|
|
20
|
+
render json: serialize_resource(result.value), status: :created
|
|
21
|
+
else
|
|
22
|
+
render_service_error(result.error, code: ERROR_CODES[:insufficient_stock])
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# PATCH /api/v3/admin/orders/:order_id/items/:id
|
|
28
|
+
def update
|
|
29
|
+
with_order_lock do
|
|
30
|
+
if permitted_params[:quantity].present?
|
|
31
|
+
result = Spree.cart_set_item_quantity_service.call(
|
|
32
|
+
order: @parent,
|
|
33
|
+
line_item: @resource,
|
|
34
|
+
quantity: permitted_params[:quantity]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
if result.success?
|
|
38
|
+
render json: serialize_resource(@resource.reload)
|
|
39
|
+
else
|
|
40
|
+
render_service_error(result.error, code: ERROR_CODES[:invalid_quantity])
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
if @resource.update(permitted_params.except(:variant_id, :quantity))
|
|
44
|
+
render json: serialize_resource(@resource)
|
|
45
|
+
else
|
|
46
|
+
render_errors(@resource.errors)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# DELETE /api/v3/admin/orders/:order_id/items/:id
|
|
53
|
+
def destroy
|
|
54
|
+
with_order_lock do
|
|
55
|
+
Spree.cart_remove_line_item_service.call(
|
|
56
|
+
order: @parent,
|
|
57
|
+
line_item: @resource
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
head :no_content
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
protected
|
|
65
|
+
|
|
66
|
+
def model_class
|
|
67
|
+
Spree::LineItem
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def serializer_class
|
|
71
|
+
Spree.api.admin_line_item_serializer
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def parent_association
|
|
75
|
+
:line_items
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def permitted_params
|
|
79
|
+
params.permit(:variant_id, :quantity, metadata: {}, options: {})
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def variant
|
|
85
|
+
@variant ||= current_store.variants.find_by_prefix_id!(permitted_params[:variant_id])
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module Orders
|
|
6
|
+
class PaymentsController < BaseController
|
|
7
|
+
scoped_resource :payments
|
|
8
|
+
|
|
9
|
+
before_action :set_resource, only: [:show, :capture, :void]
|
|
10
|
+
|
|
11
|
+
# POST /api/v3/admin/orders/:order_id/payments
|
|
12
|
+
#
|
|
13
|
+
# Supports off-session admin charges by passing `source_id` referencing a
|
|
14
|
+
# saved payment source (e.g. a Spree::CreditCard owned by the order's customer).
|
|
15
|
+
# The source must belong to the customer assigned to the order.
|
|
16
|
+
def create
|
|
17
|
+
with_order_lock do
|
|
18
|
+
payment_method = Spree::PaymentMethod.find_by_prefix_id!(params[:payment_method_id])
|
|
19
|
+
@resource = @parent.payments.build(
|
|
20
|
+
amount: params[:amount] || @parent.order_total_after_store_credit,
|
|
21
|
+
payment_method: payment_method
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if params[:source_id].present? && payment_method.source_required?
|
|
25
|
+
@resource.source = find_source!(payment_method, params[:source_id])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
authorize_resource!(@resource, :create)
|
|
29
|
+
|
|
30
|
+
if @resource.save
|
|
31
|
+
render json: serialize_resource(@resource), status: :created
|
|
32
|
+
else
|
|
33
|
+
render_validation_error(@resource.errors)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# PATCH /api/v3/admin/orders/:order_id/payments/:id/capture
|
|
39
|
+
def capture
|
|
40
|
+
with_order_lock do
|
|
41
|
+
amount = params[:amount] ? (params[:amount].to_f * 100).round : nil
|
|
42
|
+
@resource.capture!(amount)
|
|
43
|
+
render json: serialize_resource(@resource.reload)
|
|
44
|
+
rescue Spree::Core::GatewayError => e
|
|
45
|
+
render_service_error(e.message)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# PATCH /api/v3/admin/orders/:order_id/payments/:id/void
|
|
50
|
+
def void
|
|
51
|
+
with_order_lock do
|
|
52
|
+
@resource.void_transaction!
|
|
53
|
+
render json: serialize_resource(@resource.reload)
|
|
54
|
+
rescue Spree::Core::GatewayError => e
|
|
55
|
+
render_service_error(e.message)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
protected
|
|
60
|
+
|
|
61
|
+
def model_class
|
|
62
|
+
Spree::Payment
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def serializer_class
|
|
66
|
+
Spree.api.admin_payment_serializer
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def parent_association
|
|
70
|
+
:payments
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def permitted_params
|
|
74
|
+
params.permit(:amount, :payment_method_id, :source_id)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Saved-source charges require an order customer — sources are scoped
|
|
78
|
+
# to that customer to prevent attaching customer A's card to
|
|
79
|
+
# customer B's order. Refuse if no customer is assigned.
|
|
80
|
+
def find_source!(payment_method, source_id)
|
|
81
|
+
raise ActiveRecord::RecordNotFound unless @parent.user
|
|
82
|
+
|
|
83
|
+
@parent.user.credit_cards.find_by_prefix_id!(source_id)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module Orders
|
|
6
|
+
class RefundsController < BaseController
|
|
7
|
+
scoped_resource :refunds
|
|
8
|
+
|
|
9
|
+
# POST /api/v3/admin/orders/:order_id/refunds
|
|
10
|
+
def create
|
|
11
|
+
with_order_lock do
|
|
12
|
+
payment = @parent.payments.find_by_prefix_id!(params[:payment_id])
|
|
13
|
+
reason = Spree::RefundReason.find_by_prefix_id!(params[:refund_reason_id]) if params[:refund_reason_id].present?
|
|
14
|
+
reason ||= Spree::RefundReason.first
|
|
15
|
+
|
|
16
|
+
@resource = payment.refunds.build(
|
|
17
|
+
amount: params[:amount],
|
|
18
|
+
reason: reason,
|
|
19
|
+
transaction_id: nil
|
|
20
|
+
)
|
|
21
|
+
authorize_resource!(@resource, :create)
|
|
22
|
+
|
|
23
|
+
if @resource.save
|
|
24
|
+
render json: serialize_resource(@resource), status: :created
|
|
25
|
+
else
|
|
26
|
+
render_validation_error(@resource.errors)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
def model_class
|
|
34
|
+
Spree::Refund
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def serializer_class
|
|
38
|
+
Spree.api.admin_refund_serializer
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def scope
|
|
42
|
+
Spree::Refund.where(payment_id: @parent.payment_ids)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def collection_includes
|
|
46
|
+
[:payment, :reason]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module Orders
|
|
6
|
+
class StoreCreditsController < BaseController
|
|
7
|
+
scoped_resource :store_credits
|
|
8
|
+
|
|
9
|
+
skip_before_action :set_resource, raise: false
|
|
10
|
+
|
|
11
|
+
# POST /api/v3/admin/orders/:order_id/store_credits
|
|
12
|
+
#
|
|
13
|
+
# Body: { amount: Number (optional) }
|
|
14
|
+
#
|
|
15
|
+
# When `amount` is omitted, applies the customer's available store
|
|
16
|
+
# credit up to the order total.
|
|
17
|
+
def create
|
|
18
|
+
with_order_lock do
|
|
19
|
+
result = Spree.checkout_add_store_credit_service.call(
|
|
20
|
+
order: @parent,
|
|
21
|
+
amount: params[:amount].try(:to_f)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if result.success?
|
|
25
|
+
render json: serialize_resource(result.value), status: :created
|
|
26
|
+
else
|
|
27
|
+
render_service_error(result.error)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# DELETE /api/v3/admin/orders/:order_id/store_credits
|
|
33
|
+
def destroy
|
|
34
|
+
with_order_lock do
|
|
35
|
+
result = Spree.checkout_remove_store_credit_service.call(order: @parent)
|
|
36
|
+
|
|
37
|
+
if result.success?
|
|
38
|
+
head :no_content
|
|
39
|
+
else
|
|
40
|
+
render_service_error(result.error)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
protected
|
|
46
|
+
|
|
47
|
+
def model_class
|
|
48
|
+
Spree::Order
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def serializer_class
|
|
52
|
+
Spree.api.admin_order_serializer
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class OrdersController < ResourceController
|
|
6
|
+
include Spree::Api::V3::OrderLock
|
|
7
|
+
|
|
8
|
+
scoped_resource :orders
|
|
9
|
+
|
|
10
|
+
skip_before_action :set_resource, only: [:index, :create]
|
|
11
|
+
before_action :set_resource, only: [:show, :update, :destroy, :complete, :cancel, :approve, :resume, :resend_confirmation]
|
|
12
|
+
|
|
13
|
+
# POST /api/v3/admin/orders
|
|
14
|
+
def create
|
|
15
|
+
authorize!(:create, Spree::Order)
|
|
16
|
+
|
|
17
|
+
result = Spree.order_create_service.call(
|
|
18
|
+
store: current_store,
|
|
19
|
+
user: resolve_user,
|
|
20
|
+
params: order_create_params
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if result.success?
|
|
24
|
+
@resource = result.value
|
|
25
|
+
render json: serialize_resource(@resource), status: :created
|
|
26
|
+
else
|
|
27
|
+
render_service_error(result.error)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# PATCH /api/v3/admin/orders/:id
|
|
32
|
+
def update
|
|
33
|
+
with_order_lock do
|
|
34
|
+
result = Spree.order_update_service.call(
|
|
35
|
+
order: @resource,
|
|
36
|
+
params: order_update_params
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
if result.success?
|
|
40
|
+
render json: serialize_resource(result.value)
|
|
41
|
+
else
|
|
42
|
+
render_validation_error(@resource.errors.presence || result.error)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# PATCH /api/v3/admin/orders/:id/complete
|
|
48
|
+
def complete
|
|
49
|
+
with_order_lock do
|
|
50
|
+
result = Spree.order_complete_service.call(
|
|
51
|
+
order: @resource,
|
|
52
|
+
payment_pending: ActiveModel::Type::Boolean.new.cast(params[:payment_pending]),
|
|
53
|
+
notify_customer: ActiveModel::Type::Boolean.new.cast(params[:notify_customer])
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if result.success?
|
|
57
|
+
render json: serialize_resource(@resource.reload)
|
|
58
|
+
else
|
|
59
|
+
render_service_error(@resource.errors.presence || result.error, code: ERROR_CODES[:order_cannot_complete])
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# PATCH /api/v3/admin/orders/:id/cancel
|
|
65
|
+
def cancel
|
|
66
|
+
with_order_lock do
|
|
67
|
+
@resource.canceled_by(try_spree_current_user)
|
|
68
|
+
render json: serialize_resource(@resource.reload)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# PATCH /api/v3/admin/orders/:id/approve
|
|
73
|
+
def approve
|
|
74
|
+
with_order_lock do
|
|
75
|
+
@resource.approved_by(try_spree_current_user)
|
|
76
|
+
render json: serialize_resource(@resource.reload)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# PATCH /api/v3/admin/orders/:id/resume
|
|
81
|
+
def resume
|
|
82
|
+
with_order_lock do
|
|
83
|
+
@resource.resume!
|
|
84
|
+
render json: serialize_resource(@resource.reload)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# POST /api/v3/admin/orders/:id/resend_confirmation
|
|
89
|
+
def resend_confirmation
|
|
90
|
+
@resource.publish_event('order.completed')
|
|
91
|
+
render json: serialize_resource(@resource)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
protected
|
|
95
|
+
|
|
96
|
+
def model_class
|
|
97
|
+
Spree::Order
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def serializer_class
|
|
101
|
+
Spree.api.admin_order_serializer
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Override scope — Order uses SingleStoreResource (for_store)
|
|
105
|
+
def scope
|
|
106
|
+
current_store.orders.accessible_by(current_ability, :show).preload_associations_lazily
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def set_resource
|
|
110
|
+
@resource = scope.find_by_prefix_id!(params[:id])
|
|
111
|
+
@order = @resource # needed for OrderLock
|
|
112
|
+
authorize_resource!(@resource)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Map state transition actions to :update permission
|
|
116
|
+
def authorize_resource!(resource = @resource, action = action_name.to_sym)
|
|
117
|
+
mapped_action = case action
|
|
118
|
+
when :complete, :cancel, :approve, :resume, :resend_confirmation
|
|
119
|
+
:update
|
|
120
|
+
else
|
|
121
|
+
action
|
|
122
|
+
end
|
|
123
|
+
authorize!(mapped_action, resource)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def collection_includes
|
|
127
|
+
[:line_items, :user, :channel, :rich_text_internal_note]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
def resolve_user
|
|
133
|
+
customer_param = params[:customer_id].presence || params[:user_id].presence
|
|
134
|
+
return unless customer_param
|
|
135
|
+
|
|
136
|
+
Spree.user_class.find_by_param!(customer_param)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def order_create_params
|
|
140
|
+
normalize_params(
|
|
141
|
+
params.permit(
|
|
142
|
+
:email, :customer_id, :user_id, :use_customer_default_address,
|
|
143
|
+
:currency, :market_id, :channel_id, :locale,
|
|
144
|
+
:customer_note, :internal_note,
|
|
145
|
+
:shipping_address_id, :billing_address_id,
|
|
146
|
+
:preferred_stock_location_id,
|
|
147
|
+
:coupon_code,
|
|
148
|
+
metadata: {},
|
|
149
|
+
tags: [],
|
|
150
|
+
shipping_address: address_permitted_keys,
|
|
151
|
+
billing_address: address_permitted_keys,
|
|
152
|
+
items: item_permitted_keys
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def order_update_params
|
|
158
|
+
normalize_params(
|
|
159
|
+
params.permit(
|
|
160
|
+
:email, :customer_id, :user_id,
|
|
161
|
+
:customer_note, :internal_note,
|
|
162
|
+
:currency, :locale, :market_id, :channel_id,
|
|
163
|
+
:preferred_stock_location_id,
|
|
164
|
+
metadata: {},
|
|
165
|
+
tags: [],
|
|
166
|
+
ship_address: address_permitted_keys,
|
|
167
|
+
bill_address: address_permitted_keys,
|
|
168
|
+
items: item_permitted_keys
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def address_permitted_keys
|
|
174
|
+
[
|
|
175
|
+
:firstname, :lastname, :first_name, :last_name,
|
|
176
|
+
:address1, :address2, :city,
|
|
177
|
+
:country_iso, :state_abbr, :country_id, :state_id,
|
|
178
|
+
:zipcode, :postal_code, :phone, :alternative_phone,
|
|
179
|
+
:state_name, :company, :label
|
|
180
|
+
]
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def item_permitted_keys
|
|
184
|
+
[:variant_id, :quantity, { metadata: {} }]
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class PaymentMethodsController < ResourceController
|
|
6
|
+
include Spree::Api::V3::Admin::SubclassedResource
|
|
7
|
+
|
|
8
|
+
scoped_resource :settings
|
|
9
|
+
|
|
10
|
+
subclassed_via -> { Spree::PaymentMethod.providers },
|
|
11
|
+
unknown_type_error: 'unknown_payment_method_type'
|
|
12
|
+
|
|
13
|
+
# Lists available payment provider subclasses for the create form.
|
|
14
|
+
# Returns: { data: [{ type, label, description, preference_schema }] }.
|
|
15
|
+
# The preference_schema array describes the provider-specific
|
|
16
|
+
# configuration fields, so admin UIs can render a generic
|
|
17
|
+
# preferences form without hard-coding per-provider knowledge.
|
|
18
|
+
# Filters out subclasses already installed in the current store —
|
|
19
|
+
# mirrors the legacy admin's "available_payment_methods" helper, so
|
|
20
|
+
# admins don't see (and accidentally double-install) the same
|
|
21
|
+
# provider twice.
|
|
22
|
+
def types
|
|
23
|
+
authorize! :create, model_class
|
|
24
|
+
|
|
25
|
+
# Query via direct join rather than `current_store.payment_methods`
|
|
26
|
+
# — the has_many-through association can cache stale results when
|
|
27
|
+
# `current_store` was loaded earlier in the request (e.g. by the
|
|
28
|
+
# auth layer).
|
|
29
|
+
installed_class_names = Spree::PaymentMethod
|
|
30
|
+
.joins(:store_payment_methods)
|
|
31
|
+
.where(spree_payment_methods_stores: { store_id: current_store.id })
|
|
32
|
+
.pluck(:type)
|
|
33
|
+
installed_shorthands = installed_class_names.filter_map do |name|
|
|
34
|
+
name.safe_constantize&.api_type
|
|
35
|
+
end
|
|
36
|
+
available = model_class.subclasses_with_preference_schema.reject do |entry|
|
|
37
|
+
installed_shorthands.include?(entry[:type])
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
render json: { data: available }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
protected
|
|
44
|
+
|
|
45
|
+
def model_class
|
|
46
|
+
Spree::PaymentMethod
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def serializer_class
|
|
50
|
+
Spree.api.admin_payment_method_serializer
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Explicit allowlist per the v3 convention — flat params, no
|
|
54
|
+
# reach into the global `Spree::PermittedAttributes` registry
|
|
55
|
+
# (which is the legacy Rails admin's surface). `type` and
|
|
56
|
+
# `preferences` are added by `SubclassedResource` on top.
|
|
57
|
+
def permitted_params
|
|
58
|
+
params.permit(:name, :description, :active, :storefront_visible, :auto_capture, :position, metadata: {}, preferences: {})
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# New payment methods get scoped to the current store automatically.
|
|
64
|
+
def build_subclassed_resource(klass, attrs)
|
|
65
|
+
resource = klass.new(attrs)
|
|
66
|
+
resource.stores = [current_store] if resource.stores.empty?
|
|
67
|
+
resource
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|