spree_api 6.0.0.rc1 → 6.0.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +0 -17
  3. data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +10 -0
  4. data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +26 -4
  5. data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +14 -28
  6. data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +1 -1
  7. data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +3 -2
  8. data/app/controllers/concerns/spree/api/v3/channel_resolution.rb +1 -1
  9. data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +3 -1
  10. data/app/controllers/concerns/spree/api/v3/error_handler.rb +48 -2
  11. data/app/controllers/concerns/spree/api/v3/file_uploads.rb +35 -0
  12. data/app/controllers/concerns/spree/api/v3/money_params.rb +52 -0
  13. data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +1 -5
  14. data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +6 -6
  15. data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +1 -4
  16. data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +1 -5
  17. data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +1 -4
  18. data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +5 -21
  19. data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +5 -0
  20. data/app/controllers/concerns/spree/api/v3/purchase_serialization.rb +26 -0
  21. data/app/controllers/concerns/spree/api/v3/request_params.rb +65 -0
  22. data/app/controllers/concerns/spree/api/v3/strict_money_params.rb +94 -0
  23. data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +10 -1
  24. data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +8 -1
  25. data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +15 -7
  26. data/app/controllers/spree/api/v3/admin/base_controller.rb +1 -0
  27. data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +3 -1
  28. data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +7 -5
  29. data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +60 -33
  30. data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +4 -1
  31. data/app/controllers/spree/api/v3/admin/categories_controller.rb +40 -20
  32. data/app/controllers/spree/api/v3/admin/channels_controller.rb +39 -6
  33. data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +5 -1
  34. data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +4 -1
  35. data/app/controllers/spree/api/v3/admin/collections_controller.rb +44 -15
  36. data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +60 -12
  37. data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +11 -0
  38. data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +9 -1
  39. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +19 -18
  40. data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +6 -1
  41. data/app/controllers/spree/api/v3/admin/companies_controller.rb +17 -3
  42. data/app/controllers/spree/api/v3/admin/countries_controller.rb +5 -1
  43. data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +21 -11
  44. data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +12 -5
  45. data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +9 -1
  46. data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +12 -7
  47. data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +11 -9
  48. data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +6 -1
  49. data/app/controllers/spree/api/v3/admin/customers_controller.rb +35 -7
  50. data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +8 -0
  51. data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +1 -1
  52. data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +15 -7
  53. data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +92 -57
  54. data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +8 -1
  55. data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +13 -1
  56. data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +21 -5
  57. data/app/controllers/spree/api/v3/admin/email_templates/drafts_controller.rb +14 -1
  58. data/app/controllers/spree/api/v3/admin/email_templates/previews_controller.rb +4 -0
  59. data/app/controllers/spree/api/v3/admin/email_templates/publications_controller.rb +7 -0
  60. data/app/controllers/spree/api/v3/admin/email_templates/restorations_controller.rb +8 -0
  61. data/app/controllers/spree/api/v3/admin/email_templates/test_emails_controller.rb +4 -0
  62. data/app/controllers/spree/api/v3/admin/exports_controller.rb +23 -6
  63. data/app/controllers/spree/api/v3/admin/files_controller.rb +29 -0
  64. data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +20 -1
  65. data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +19 -1
  66. data/app/controllers/spree/api/v3/admin/imports_controller.rb +36 -9
  67. data/app/controllers/spree/api/v3/admin/integrations_controller.rb +13 -1
  68. data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +9 -2
  69. data/app/controllers/spree/api/v3/admin/invitations_controller.rb +8 -1
  70. data/app/controllers/spree/api/v3/admin/locales_controller.rb +1 -1
  71. data/app/controllers/spree/api/v3/admin/markets_controller.rb +30 -9
  72. data/app/controllers/spree/api/v3/admin/me_controller.rb +12 -3
  73. data/app/controllers/spree/api/v3/admin/media_controller.rb +22 -9
  74. data/app/controllers/spree/api/v3/admin/media_library_controller.rb +4 -0
  75. data/app/controllers/spree/api/v3/admin/option_types_controller.rb +24 -7
  76. data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +5 -1
  77. data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +13 -1
  78. data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +39 -1
  79. data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +19 -1
  80. data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +5 -1
  81. data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +29 -5
  82. data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +36 -1
  83. data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +22 -1
  84. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +66 -7
  85. data/app/controllers/spree/api/v3/admin/orders/gift_cards_controller.rb +6 -2
  86. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +11 -1
  87. data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +35 -2
  88. data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +16 -5
  89. data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +6 -0
  90. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +37 -1
  91. data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +6 -3
  92. data/app/controllers/spree/api/v3/admin/orders_controller.rb +74 -60
  93. data/app/controllers/spree/api/v3/admin/package_types_controller.rb +30 -5
  94. data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +17 -0
  95. data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +38 -22
  96. data/app/controllers/spree/api/v3/admin/policies_controller.rb +8 -4
  97. data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +27 -15
  98. data/app/controllers/spree/api/v3/admin/prices_controller.rb +51 -4
  99. data/app/controllers/spree/api/v3/admin/product_types_controller.rb +25 -8
  100. data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +27 -10
  101. data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +9 -14
  102. data/app/controllers/spree/api/v3/admin/products_controller.rb +121 -70
  103. data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +11 -2
  104. data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +10 -1
  105. data/app/controllers/spree/api/v3/admin/promotions_controller.rb +50 -14
  106. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +54 -7
  107. data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +5 -1
  108. data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +9 -1
  109. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +34 -0
  110. data/app/controllers/spree/api/v3/admin/resource_controller.rb +1 -0
  111. data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +5 -1
  112. data/app/controllers/spree/api/v3/admin/roles_controller.rb +13 -1
  113. data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +6 -0
  114. data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +15 -0
  115. data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +32 -6
  116. data/app/controllers/spree/api/v3/admin/sellers_controller.rb +75 -22
  117. data/app/controllers/spree/api/v3/admin/setup_controller.rb +54 -15
  118. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +38 -9
  119. data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +41 -9
  120. data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +48 -7
  121. data/app/controllers/spree/api/v3/admin/store_controller.rb +122 -53
  122. data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +1 -7
  123. data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +16 -6
  124. data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +7 -4
  125. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +21 -3
  126. data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +4 -0
  127. data/app/controllers/spree/api/v3/admin/translations/batches_controller.rb +17 -9
  128. data/app/controllers/spree/api/v3/admin/translations_controller.rb +4 -0
  129. data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +5 -0
  130. data/app/controllers/spree/api/v3/admin/updates_controller.rb +39 -0
  131. data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +23 -1
  132. data/app/controllers/spree/api/v3/base_controller.rb +2 -0
  133. data/app/controllers/spree/api/v3/resource_controller.rb +63 -10
  134. data/app/controllers/spree/api/v3/seller/auth_controller.rb +8 -0
  135. data/app/controllers/spree/api/v3/seller/base_controller.rb +1 -0
  136. data/app/controllers/spree/api/v3/seller/countries_controller.rb +2 -2
  137. data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +49 -60
  138. data/app/controllers/spree/api/v3/seller/exports_controller.rb +18 -1
  139. data/app/controllers/spree/api/v3/seller/files_controller.rb +27 -0
  140. data/app/controllers/spree/api/v3/seller/imports_controller.rb +25 -9
  141. data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +9 -1
  142. data/app/controllers/spree/api/v3/seller/me_controller.rb +14 -3
  143. data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +11 -0
  144. data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +35 -0
  145. data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +12 -0
  146. data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +33 -0
  147. data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +28 -2
  148. data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +22 -1
  149. data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +8 -1
  150. data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +32 -0
  151. data/app/controllers/spree/api/v3/seller/orders_controller.rb +35 -14
  152. data/app/controllers/spree/api/v3/seller/package_types_controller.rb +21 -9
  153. data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +10 -0
  154. data/app/controllers/spree/api/v3/seller/policies_controller.rb +12 -4
  155. data/app/controllers/spree/api/v3/seller/products_controller.rb +114 -28
  156. data/app/controllers/spree/api/v3/seller/profile_controller.rb +33 -10
  157. data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +12 -5
  158. data/app/controllers/spree/api/v3/seller/resource_controller.rb +12 -0
  159. data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +44 -13
  160. data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +10 -1
  161. data/app/controllers/spree/api/v3/seller/team_controller.rb +4 -0
  162. data/app/controllers/spree/api/v3/store/auth_controller.rb +10 -0
  163. data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +8 -1
  164. data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +10 -2
  165. data/app/controllers/spree/api/v3/store/carts/gift_cards_controller.rb +8 -1
  166. data/app/controllers/spree/api/v3/store/carts/items_controller.rb +17 -5
  167. data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +20 -6
  168. data/app/controllers/spree/api/v3/store/carts/payments_controller.rb +11 -0
  169. data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +24 -26
  170. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +7 -1
  171. data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +5 -1
  172. data/app/controllers/spree/api/v3/store/carts_controller.rb +56 -47
  173. data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +12 -4
  174. data/app/controllers/spree/api/v3/store/companies/members_controller.rb +4 -0
  175. data/app/controllers/spree/api/v3/store/companies_controller.rb +5 -1
  176. data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +9 -1
  177. data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +8 -7
  178. data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +5 -0
  179. data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +17 -0
  180. data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +10 -5
  181. data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +5 -1
  182. data/app/controllers/spree/api/v3/store/customers_controller.rb +28 -2
  183. data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +22 -0
  184. data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +11 -2
  185. data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +10 -1
  186. data/app/controllers/spree/api/v3/store/orders_controller.rb +47 -10
  187. data/app/controllers/spree/api/v3/store/products_controller.rb +8 -0
  188. data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +10 -4
  189. data/app/controllers/spree/api/v3/store/wishlists_controller.rb +12 -4
  190. data/app/request_schemas/spree/api/v3/address_request_schema.rb +27 -0
  191. data/app/request_schemas/spree/api/v3/admin/address_request_schema.rb +13 -0
  192. data/app/request_schemas/spree/api/v3/admin/bulk_tags_request_schema.rb +17 -0
  193. data/app/request_schemas/spree/api/v3/admin/catalog_order_minimum_request_schema.rb +17 -0
  194. data/app/request_schemas/spree/api/v3/admin/email_template_language_request_schema.rb +17 -0
  195. data/app/request_schemas/spree/api/v3/admin/email_template_preview_request_schema.rb +32 -0
  196. data/app/request_schemas/spree/api/v3/admin/price_adjustment_tier_request_schema.rb +21 -0
  197. data/app/request_schemas/spree/api/v3/admin/price_list_price_request_schema.rb +21 -0
  198. data/app/request_schemas/spree/api/v3/admin/price_list_rule_request_schema.rb +19 -0
  199. data/app/request_schemas/spree/api/v3/admin/product_membership_reposition_request_schema.rb +17 -0
  200. data/app/request_schemas/spree/api/v3/admin/promotion_action_calculator_request_schema.rb +18 -0
  201. data/app/request_schemas/spree/api/v3/admin/promotion_action_line_item_request_schema.rb +15 -0
  202. data/app/request_schemas/spree/api/v3/admin/promotion_action_request_schema.rb +19 -0
  203. data/app/request_schemas/spree/api/v3/admin/promotion_rule_request_schema.rb +22 -0
  204. data/app/request_schemas/spree/api/v3/admin/reason_request_schema.rb +14 -0
  205. data/app/request_schemas/spree/api/v3/admin/tax_identifier_request_schema.rb +15 -0
  206. data/app/request_schemas/spree/api/v3/custom_field_value_request_schema.rb +15 -0
  207. data/app/request_schemas/spree/api/v3/file_upload_request_schema.rb +20 -0
  208. data/app/request_schemas/spree/api/v3/media_request_schema.rb +27 -0
  209. data/app/request_schemas/spree/api/v3/price_request_schema.rb +17 -0
  210. data/app/request_schemas/spree/api/v3/stock_level_request_schema.rb +18 -0
  211. data/app/request_schemas/spree/api/v3/store/address_request_schema.rb +29 -0
  212. data/app/request_schemas/spree/api/v3/tax_identifier_request_schema.rb +18 -0
  213. data/app/request_schemas/spree/api/v3/variant_option_request_schema.rb +13 -0
  214. data/app/request_schemas/spree/api/v3/variant_request_schema.rb +52 -0
  215. data/app/serializers/concerns/spree/api/v3/purchase_summary.rb +48 -0
  216. data/app/serializers/spree/api/v3/address_serializer.rb +4 -2
  217. data/app/serializers/spree/api/v3/admin/address_serializer.rb +3 -0
  218. data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +3 -1
  219. data/app/serializers/spree/api/v3/admin/cart_serializer.rb +3 -1
  220. data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +3 -2
  221. data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +3 -4
  222. data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +4 -3
  223. data/app/serializers/spree/api/v3/admin/channel_serializer.rb +5 -7
  224. data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +7 -0
  225. data/app/serializers/spree/api/v3/admin/claim_serializer.rb +5 -0
  226. data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +7 -18
  227. data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +7 -11
  228. data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +0 -2
  229. data/app/serializers/spree/api/v3/admin/country_serializer.rb +4 -0
  230. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +3 -7
  231. data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +0 -2
  232. data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +14 -10
  233. data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +9 -1
  234. data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +8 -0
  235. data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -1
  236. data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +5 -0
  237. data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +5 -0
  238. data/app/serializers/spree/api/v3/admin/fee_serializer.rb +3 -1
  239. data/app/serializers/spree/api/v3/admin/file_upload_serializer.rb +11 -0
  240. data/app/serializers/spree/api/v3/admin/file_upload_target_serializer.rb +10 -0
  241. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +13 -11
  242. data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +3 -3
  243. data/app/serializers/spree/api/v3/admin/import_serializer.rb +2 -2
  244. data/app/serializers/spree/api/v3/admin/integration_serializer.rb +1 -3
  245. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +12 -12
  246. data/app/serializers/spree/api/v3/admin/locale_serializer.rb +13 -0
  247. data/app/serializers/spree/api/v3/admin/market_serializer.rb +3 -0
  248. data/app/serializers/spree/api/v3/admin/media_serializer.rb +3 -2
  249. data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +2 -0
  250. data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +1 -3
  251. data/app/serializers/spree/api/v3/admin/order_serializer.rb +33 -33
  252. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +1 -4
  253. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -3
  254. data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +8 -9
  255. data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +3 -6
  256. data/app/serializers/spree/api/v3/admin/price_history_serializer.rb +5 -2
  257. data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +1 -5
  258. data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +1 -3
  259. data/app/serializers/spree/api/v3/admin/price_serializer.rb +2 -0
  260. data/app/serializers/spree/api/v3/admin/product_serializer.rb +2 -0
  261. data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +4 -6
  262. data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +0 -2
  263. data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +5 -11
  264. data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +4 -4
  265. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +7 -3
  266. data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +9 -2
  267. data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +8 -0
  268. data/app/serializers/spree/api/v3/admin/return_serializer.rb +8 -4
  269. data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +15 -10
  270. data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +3 -5
  271. data/app/serializers/spree/api/v3/admin/seller_serializer.rb +3 -1
  272. data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +7 -8
  273. data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +4 -4
  274. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +3 -0
  275. data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +2 -6
  276. data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +5 -0
  277. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +9 -4
  278. data/app/serializers/spree/api/v3/admin/store_serializer.rb +17 -98
  279. data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +1 -1
  280. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +3 -1
  281. data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +4 -2
  282. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +2 -12
  283. data/app/serializers/spree/api/v3/admin/update_status_serializer.rb +28 -0
  284. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +7 -3
  285. data/app/serializers/spree/api/v3/base_serializer.rb +112 -7
  286. data/app/serializers/spree/api/v3/cart_serializer.rb +11 -29
  287. data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +5 -13
  288. data/app/serializers/spree/api/v3/claim_serializer.rb +2 -3
  289. data/app/serializers/spree/api/v3/country_serializer.rb +2 -1
  290. data/app/serializers/spree/api/v3/currency_serializer.rb +9 -1
  291. data/app/serializers/spree/api/v3/customer_serializer.rb +3 -2
  292. data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +8 -12
  293. data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +1 -1
  294. data/app/serializers/spree/api/v3/discount_serializer.rb +4 -1
  295. data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +2 -8
  296. data/app/serializers/spree/api/v3/exchange_serializer.rb +2 -3
  297. data/app/serializers/spree/api/v3/file_upload_serializer.rb +28 -0
  298. data/app/serializers/spree/api/v3/file_upload_target_serializer.rb +17 -0
  299. data/app/serializers/spree/api/v3/gift_card_batch_serializer.rb +2 -4
  300. data/app/serializers/spree/api/v3/gift_card_serializer.rb +4 -2
  301. data/app/serializers/spree/api/v3/import_serializer.rb +0 -12
  302. data/app/serializers/spree/api/v3/line_item_serializer.rb +15 -5
  303. data/app/serializers/spree/api/v3/locale_serializer.rb +3 -1
  304. data/app/serializers/spree/api/v3/market_serializer.rb +5 -5
  305. data/app/serializers/spree/api/v3/media_serializer.rb +7 -2
  306. data/app/serializers/spree/api/v3/order_group_serializer.rb +12 -4
  307. data/app/serializers/spree/api/v3/order_serializer.rb +5 -23
  308. data/app/serializers/spree/api/v3/payment_session_serializer.rb +2 -4
  309. data/app/serializers/spree/api/v3/price_history_serializer.rb +5 -5
  310. data/app/serializers/spree/api/v3/price_serializer.rb +6 -9
  311. data/app/serializers/spree/api/v3/product_filter_price_range_serializer.rb +10 -4
  312. data/app/serializers/spree/api/v3/product_serializer.rb +3 -3
  313. data/app/serializers/spree/api/v3/refund_serializer.rb +8 -5
  314. data/app/serializers/spree/api/v3/return_line_item_serializer.rb +3 -11
  315. data/app/serializers/spree/api/v3/return_serializer.rb +3 -6
  316. data/app/serializers/spree/api/v3/seller/address_serializer.rb +12 -0
  317. data/app/serializers/spree/api/v3/seller/balance_serializer.rb +15 -10
  318. data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +7 -0
  319. data/app/serializers/spree/api/v3/seller/claim_serializer.rb +5 -0
  320. data/app/serializers/spree/api/v3/seller/country_serializer.rb +19 -0
  321. data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +1 -3
  322. data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +4 -8
  323. data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +9 -8
  324. data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +5 -0
  325. data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +5 -0
  326. data/app/serializers/spree/api/v3/seller/file_upload_serializer.rb +11 -0
  327. data/app/serializers/spree/api/v3/seller/file_upload_target_serializer.rb +10 -0
  328. data/app/serializers/spree/api/v3/seller/import_serializer.rb +2 -2
  329. data/app/serializers/spree/api/v3/seller/media_serializer.rb +2 -5
  330. data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +4 -3
  331. data/app/serializers/spree/api/v3/seller/order_serializer.rb +16 -16
  332. data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +8 -9
  333. data/app/serializers/spree/api/v3/seller/payout_serializer.rb +2 -4
  334. data/app/serializers/spree/api/v3/seller/price_history_serializer.rb +11 -0
  335. data/app/serializers/spree/api/v3/seller/price_serializer.rb +11 -0
  336. data/app/serializers/spree/api/v3/seller/product_serializer.rb +2 -0
  337. data/app/serializers/spree/api/v3/seller/profile_serializer.rb +7 -7
  338. data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +8 -0
  339. data/app/serializers/spree/api/v3/seller/return_serializer.rb +8 -5
  340. data/app/serializers/spree/api/v3/seller/state_serializer.rb +10 -0
  341. data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +3 -0
  342. data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +6 -7
  343. data/app/serializers/spree/api/v3/seller/variant_serializer.rb +8 -4
  344. data/app/serializers/spree/api/v3/stock_location_serializer.rb +8 -1
  345. data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +1 -3
  346. data/app/serializers/spree/api/v3/store_credit_serializer.rb +3 -5
  347. data/app/serializers/spree/api/v3/tax_line_serializer.rb +2 -4
  348. data/app/serializers/spree/api/v3/variant_serializer.rb +3 -3
  349. data/app/services/spree/api/v3/filter_predicates.rb +29 -0
  350. data/app/services/spree/api/v3/filter_table.rb +337 -0
  351. data/app/services/spree/api/v3/filters_aggregator.rb +2 -2
  352. data/app/services/spree/api/v3/request_schema.rb +430 -0
  353. data/app/services/spree/webhooks/deliver_webhook.rb +7 -3
  354. data/config/initializers/typelizer.rb +1 -1
  355. data/config/routes.rb +5 -3
  356. data/lib/spree/api/configuration.rb +5 -0
  357. data/lib/spree/api/dependencies.rb +7 -6
  358. data/lib/spree/api/middleware/request_size_limit.rb +24 -3
  359. data/lib/spree/api/openapi/filter_documentation.rb +136 -0
  360. data/lib/spree/api/openapi/schema_helper.rb +126 -80
  361. data/lib/spree/api/preference_families.rb +46 -0
  362. data/lib/spree/api/preference_types.rb +138 -0
  363. data/lib/spree/api/typelizer_generation.rb +4 -0
  364. data/lib/tasks/filters.rake +12 -0
  365. data/lib/typelizer/open_enums.rb +10 -0
  366. metadata +60 -10
  367. data/app/controllers/concerns/spree/api/v3/address_params.rb +0 -17
  368. data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +0 -35
  369. data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +0 -54
  370. data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +0 -21
@@ -4,6 +4,16 @@ module Spree
4
4
  module Admin
5
5
  module Orders
6
6
  class ItemsController < BaseController
7
+ request_params :line_item do |body|
8
+ body.attribute :variant_id, :id, required: true, only: :create
9
+ body.attribute :quantity, :integer, example: 1, description: 'Defaults to 1 when adding an item.'
10
+ body.attribute :price, :decimal,
11
+ nullable: true,
12
+ description: "Negotiated unit price. Stamps the line `price_source: 'manual'`, so quantity changes and recalculation never re-price it; an explicit null reverts the line to catalog pricing. Omit to leave pricing alone. Draft (incomplete) orders only."
13
+ body.attribute :options, :hash, only: :create
14
+ body.attribute :metadata, :hash, only: :update
15
+ end
16
+
7
17
  # POST /api/v3/admin/orders/:order_id/items
8
18
  def create
9
19
  with_order_lock do
@@ -69,7 +79,7 @@ module Spree
69
79
  end
70
80
 
71
81
  def permitted_params
72
- params.permit(:variant_id, :quantity, :price, metadata: {}, options: {})
82
+ params.permit(*permitted_attributes)
73
83
  end
74
84
 
75
85
  private
@@ -11,16 +11,39 @@ module Spree
11
11
  class LabelsController < BaseController
12
12
  include Spree::Api::V3::Orders::ShippingLabelActions
13
13
 
14
+ # The permit list itself lives in ShippingLabelActions, shared with
15
+ # the seller branch; this declaration documents it.
16
+ request_params :shipping_label do |body|
17
+ body.attribute :file_signed_id, :string,
18
+ description: 'A `signed_id` from `files.upload()`. Its presence records a label bought elsewhere instead of buying one; without it the body is ignored and the label is bought through the carrier.'
19
+ body.attribute :tracking_number, :string,
20
+ description: 'The number printed on an uploaded label. Required with `file_signed_id`.'
21
+ body.attribute :carrier, :string,
22
+ description: "Free text; a forwarder's name is as valid as a carrier slug. Detected from the number when omitted."
23
+ body.attribute :service, :string, description: 'Carrier service the label was bought at.'
24
+ body.attribute :cost, :decimal,
25
+ description: "What the merchant paid the carrier. Accounting data only; it never touches the order's shipping charge."
26
+ body.attribute :currency, :currency, description: 'Currency of the cost.'
27
+ body.attribute :file_format, :string,
28
+ choices: %w[pdf png zpl],
29
+ description: 'Taken from the file when omitted.'
30
+ body.attribute :tracking_url, :string, description: 'Tracking page for the consignment the label mints.'
31
+ end
32
+
14
33
  before_action :set_resource, only: [:show, :download, :refund, :destroy]
15
34
 
16
35
  # POST .../labels
17
36
  #
18
- # Buys the label through the parcel's provider, or — when a `file`
37
+ # Buys the label through the parcel's provider, or — when a `file_signed_id`
19
38
  # is given — records one the merchant bought elsewhere.
20
39
  def create
21
40
  authorize!(:create, Spree::ShippingLabel)
22
41
 
23
- return record_uploaded_label if label_params[:file].present?
42
+ return record_uploaded_label if label_params[:file_signed_id].present?
43
+ # Buying is the default only when no file is sent at all. A file
44
+ # under its old name would otherwise fall through to buying a
45
+ # label on the carrier account.
46
+ return render_misnamed_label_file if params.key?(:file)
24
47
 
25
48
  with_order_lock do
26
49
  result = Spree.shipping_label_purchase_workflow.call(owner: @parent)
@@ -59,6 +82,16 @@ module Spree
59
82
  @order.fulfillments.find_by_prefix_id!(params[:fulfillment_id])
60
83
  end
61
84
  end
85
+
86
+ private
87
+
88
+ def render_misnamed_label_file
89
+ render_error(
90
+ code: ERROR_CODES[:parameter_invalid],
91
+ message: I18n.t('spree.shipping_labels.errors.file_renamed'),
92
+ status: :unprocessable_content
93
+ )
94
+ end
62
95
  end
63
96
  end
64
97
  end
@@ -6,6 +6,18 @@ module Spree
6
6
  class PaymentsController < BaseController
7
7
  scoped_resource :payments
8
8
 
9
+ request_params :payment do |body|
10
+ body.attribute :payment_method_id, :id, required: true, on: :create
11
+ body.attribute :amount, :decimal, description: "Defaults to the order total left after store credit."
12
+ body.attribute :source_id, :id,
13
+ description: "A saved payment source of the order's customer (a credit card), for an off-session charge. Used only by payment methods that require a source."
14
+ end
15
+
16
+ request_params 'PaymentCaptureParams', action: :capture do |body|
17
+ body.attribute :amount, :decimal,
18
+ description: 'Captures part of the authorized amount. Defaults to all of it.'
19
+ end
20
+
9
21
  before_action :set_resource, only: [:show, :capture, :void]
10
22
 
11
23
  # POST /api/v3/admin/orders/:order_id/payments
@@ -52,7 +64,10 @@ module Spree
52
64
  # to prevent. Both flows are idempotent on replay — an
53
65
  # already-captured or already-void payment returns success.
54
66
  def capture
55
- amount = params[:amount] ? (params[:amount].to_f * 100).round : nil
67
+ amount = money_param(:amount, @resource.currency)
68
+ unless amount.nil? || amount.positive?
69
+ raise Spree::Money::InvalidFormat.new('must be greater than 0', field: :amount)
70
+ end
56
71
 
57
72
  result = Spree.payment_capture_workflow.call(payment: @resource, amount: amount)
58
73
 
@@ -76,10 +91,6 @@ module Spree
76
91
  Spree.api.admin_payment_serializer
77
92
  end
78
93
 
79
- def permitted_params
80
- params.permit(:amount, :payment_method_id, :source_id)
81
- end
82
-
83
94
  # Saved-source charges require an order customer — sources are scoped
84
95
  # to that customer to prevent attaching customer A's card to
85
96
  # customer B's order. Refuse if no customer is assigned.
@@ -6,6 +6,12 @@ module Spree
6
6
  class RefundsController < BaseController
7
7
  scoped_resource :refunds
8
8
 
9
+ request_params :refund do |body|
10
+ body.attribute :payment_id, :id, required: true, on: :create
11
+ body.attribute :amount, :decimal, required: true, on: :create
12
+ body.attribute :refund_reason_id, :id, description: "Defaults to the store's first refund reason."
13
+ end
14
+
9
15
  # POST /api/v3/admin/orders/:order_id/refunds
10
16
  #
11
17
  # Deliberately not wrapped in with_order_lock: the workflow calls
@@ -19,6 +19,42 @@ module Spree
19
19
  # would be wrongly denied.
20
20
  scoped_resource :orders
21
21
 
22
+ request_params :return do |body|
23
+ body.attribute :items, :array,
24
+ required: true, on: :create,
25
+ only: :create,
26
+ description: 'Fulfilled units coming back, and how many of each.' do |item|
27
+ item.attribute :fulfillment_item_id, :id, required: true
28
+ item.attribute :quantity, :integer, required: true
29
+ end
30
+ body.attribute :stock_location_id, :id,
31
+ description: 'Where the goods come back to. Defaults to the location that shipped them.'
32
+ body.attribute :reason_id, :id, description: "One of the store's return reasons."
33
+ body.attribute :memo, :string
34
+ body.attribute :metadata, :hash, only: :update
35
+ end
36
+
37
+ request_params 'ReturnReceiveParams', action: :receive do |body|
38
+ body.attribute :items, :array,
39
+ description: 'What actually arrived. Omit to receive everything as requested and resellable; send rows for a partial or damaged receipt.' do |item|
40
+ item.attribute :return_line_item_id, :id, required: true
41
+ item.attribute :quantity, :integer, required: true
42
+ item.attribute :resellable, :boolean,
43
+ description: 'Goods that cannot be resold are received but never restocked. Defaults to true.'
44
+ end
45
+ end
46
+
47
+ request_params 'ReturnRefundParams', action: :refund do |body|
48
+ body.attribute :amount, :decimal, description: 'Defaults to the value of what was actually received.'
49
+ body.attribute :refund_method, :string,
50
+ choices: Spree::RefundMethods::METHODS,
51
+ description: '`store_credit` issues credit immediately; `original_payment` (the default) refunds through the gateway that took the money.'
52
+ end
53
+
54
+ request_params 'ReturnCancelParams', action: :cancel do |body|
55
+ body.attribute :reason, :string, description: 'A note on why the return was canceled.'
56
+ end
57
+
22
58
  before_action :set_resource, only: [:show, :update, :approve, :receive, :refund, :cancel]
23
59
 
24
60
  # PATCH /api/v3/admin/orders/:order_id/returns/:id
@@ -50,7 +86,7 @@ module Spree
50
86
  end
51
87
 
52
88
  def permitted_params
53
- params.permit(:memo, :reason_id, :stock_location_id, metadata: {})
89
+ params.permit(*permitted_attributes)
54
90
  end
55
91
 
56
92
  private
@@ -6,17 +6,20 @@ module Spree
6
6
  class StoreCreditsController < BaseController
7
7
  skip_before_action :set_resource, raise: false
8
8
 
9
+ request_params 'StoreCreditApplyParams' do |body|
10
+ body.attribute :amount, :decimal,
11
+ description: "Defaults to the customer's available store credit, up to the order total."
12
+ end
13
+
9
14
  # POST /api/v3/admin/orders/:order_id/store_credits
10
15
  #
11
- # Body: { amount: Number (optional) }
12
- #
13
16
  # When `amount` is omitted, applies the customer's available store
14
17
  # credit up to the order total.
15
18
  def create
16
19
  with_order_lock do
17
20
  result = Spree.store_credit_apply_service.call(
18
21
  order: @parent,
19
- amount: params[:amount].try(:to_f)
22
+ amount: money_param(:amount, @parent.currency)
20
23
  )
21
24
 
22
25
  if result.success?
@@ -7,11 +7,78 @@ module Spree
7
7
 
8
8
  scoped_resource :orders
9
9
 
10
- # The order accepts a `po_document` signed blob id and streams it back.
10
+ # The order accepts a `po_document_signed_id` and streams it back.
11
11
  include ActiveStorage::SetCurrent
12
12
 
13
- # A tampered signed id would otherwise surface as a 500.
14
- rescue_from ActiveSupport::MessageVerifier::InvalidSignature, with: :render_invalid_po_document
13
+ ADDRESS = Spree::Api::V3::RequestSchema.shape('AddressInputParams') do |schema|
14
+ schema.include_attributes Spree::Api::V3::Admin::AddressRequestSchema
15
+ end
16
+
17
+ request_params :order do |body|
18
+ body.external_references
19
+ body.attribute :email, :string, example: 'customer@example.com'
20
+ body.attribute :customer_id, :id
21
+ body.attribute :use_customer_default_address, :boolean,
22
+ only: :create,
23
+ description: "With `customer_id`, copies the customer's saved billing and shipping addresses onto the order."
24
+ body.attribute :currency, :currency, example: 'USD'
25
+ body.attribute :market_id, :id
26
+ body.attribute :channel_id, :id, description: 'Defaults to the store primary channel when omitted.'
27
+ body.attribute :locale, :locale, example: 'en-US'
28
+ body.attribute :customer_note, :string, description: 'Public, customer-visible note.'
29
+ body.attribute :internal_note, :string,
30
+ description: 'Staff-only note. Rich text HTML; reads come back as this plus `internal_note_html`.'
31
+ body.attribute :po_number, :string,
32
+ description: "The buyer's own purchase-order reference. Searchable alongside the order number, and rendered on every order-facing document."
33
+ body.attribute :po_document_signed_id, :string,
34
+ nullable: true,
35
+ description: "The `signed_id` of the buyer's purchase order, from `files.upload()` with `visibility: 'private'`. Null removes the document the order carries."
36
+ body.attribute :shipping_address_id, :id,
37
+ only: :create,
38
+ description: 'An existing address of the customer.'
39
+ body.attribute :billing_address_id, :id,
40
+ only: :create,
41
+ description: 'An existing address of the customer.'
42
+ body.attribute :preferred_stock_location_id, :id,
43
+ description: "Stock location to prefer for fulfillment. Order Routing's built-in preferred-location rule ranks it first; routing falls back to the next rule when the location can't cover the cart."
44
+ body.attribute :company_id, :id,
45
+ nullable: true,
46
+ description: "Makes the order a company purchase, with that company's catalog prices and tax treatment. Null makes a draft a plain customer order again."
47
+ body.attribute :coupon_code, :string,
48
+ only: :create,
49
+ description: 'Applied non-fatally: an invalid code does not block creation.'
50
+ body.attribute :metadata, :hash
51
+ body.attribute :tags, :array, of: :string
52
+ body.attribute :shipping_address, :object, shape: ADDRESS
53
+ body.attribute :billing_address, :object, shape: ADDRESS
54
+ body.attribute :items, :array,
55
+ description: 'Line items to upsert, keyed by variant. An entry sets that variant\'s quantity, creating the line item when the order has none; `quantity: 0` removes it. Variants you do not send are left alone.' do |item|
56
+ item.attribute :variant_id, :id, required: true
57
+ item.attribute :quantity, :integer, example: 1
58
+ item.attribute :price, :decimal,
59
+ nullable: true,
60
+ description: "Negotiated unit price; stamps `price_source: 'manual'`. Null reverts the line to catalog pricing. Draft orders only."
61
+ item.attribute :metadata, :hash
62
+ end
63
+ end
64
+
65
+ request_params 'OrderCompleteParams', action: :complete do |body|
66
+ body.attribute :payment_pending, :boolean
67
+ body.attribute :notify_customer, :boolean,
68
+ description: 'Send the order confirmation email after completion.'
69
+ end
70
+
71
+ request_params 'OrderCancelParams', action: :cancel do |body|
72
+ body.attribute :cancel_reason_id, :id,
73
+ description: "Why the order was canceled: the id of one of the store's cancellation reasons."
74
+ body.attribute :cancel_note, :string, description: 'Staff-facing note about the cancellation.'
75
+ body.attribute :refund_payments, :boolean,
76
+ description: "Whether this order's share of a payment shared across a split checkout is handed back."
77
+ body.attribute :refund_amount, :decimal,
78
+ description: 'How much of that share to return. Defaults to all of it; refused on an order whose payment is not shared.'
79
+ body.attribute :notify_customer, :boolean,
80
+ description: 'Send the order cancellation email after canceling.'
81
+ end
15
82
 
16
83
  skip_before_action :set_resource, only: [:index, :create]
17
84
  before_action :set_resource, only: [:show, :update, :destroy, :complete, :cancel, :approve, :resend_confirmation, :resend_digital_links, :po_document]
@@ -244,14 +311,6 @@ module Spree
244
311
 
245
312
  private
246
313
 
247
- def render_invalid_po_document
248
- render_error(
249
- code: ERROR_CODES[:validation_error],
250
- message: I18n.t('spree.po_document_invalid_signed_id'),
251
- status: :unprocessable_content
252
- )
253
- end
254
-
255
314
  def resolve_customer
256
315
  customer_param = params[:customer_id].presence
257
316
  return unless customer_param
@@ -271,44 +330,13 @@ module Spree
271
330
  end
272
331
 
273
332
  def order_create_params
274
- permitted = normalize_params(
275
- params.permit(
276
- :email, :customer_id, :use_customer_default_address,
277
- :currency, :market_id, :channel_id, :locale,
278
- :customer_note, :internal_note,
279
- # The buyer's own purchase-order reference, and the signed blob
280
- # id of the document behind it — a PO arriving by email and
281
- # keyed in is the draft-order flow plus these two fields.
282
- :po_number, :po_document,
283
- :shipping_address_id, :billing_address_id,
284
- :preferred_stock_location_id, :company_id,
285
- :coupon_code,
286
- metadata: {},
287
- tags: [],
288
- shipping_address: address_permitted_keys,
289
- billing_address: address_permitted_keys,
290
- items: item_permitted_keys
291
- )
292
- )
293
- resolve_company_param(permitted)
333
+ resolve_company_param(normalize_params(params.permit(*request_params_schema.permit_list(:create))))
294
334
  end
295
335
 
336
+ # Named rather than read from the action, since an upsert reaches
337
+ # update from the create action.
296
338
  def order_update_params
297
- permitted = normalize_params(
298
- params.permit(
299
- :email, :customer_id,
300
- :customer_note, :internal_note,
301
- :po_number, :po_document,
302
- :currency, :locale, :market_id, :channel_id,
303
- :preferred_stock_location_id, :company_id,
304
- metadata: {},
305
- tags: [],
306
- shipping_address: address_permitted_keys,
307
- billing_address: address_permitted_keys,
308
- items: item_permitted_keys
309
- )
310
- )
311
- resolve_company_param(permitted)
339
+ resolve_company_param(normalize_params(params.permit(*request_params_schema.permit_list(:update))))
312
340
  end
313
341
 
314
342
  # An incidental lookup like any other: resolved through the store so
@@ -326,20 +354,6 @@ module Spree
326
354
  end
327
355
  permitted
328
356
  end
329
-
330
- def address_permitted_keys
331
- [
332
- :firstname, :lastname, :first_name, :last_name,
333
- :address1, :address2, :city,
334
- :country_code, :state_code,
335
- :zipcode, :postal_code, :phone, :alternative_phone,
336
- :state_name, :company, :label
337
- ]
338
- end
339
-
340
- def item_permitted_keys
341
- [:variant_id, :quantity, :price, { metadata: {} }]
342
- end
343
357
  end
344
358
  end
345
359
  end
@@ -14,6 +14,36 @@ module Spree
14
14
  class PackageTypesController < ResourceController
15
15
  scoped_resource :package_types
16
16
 
17
+ request_params :package_type do |body|
18
+ body.attribute :name, :string,
19
+ required: true, on: :create,
20
+ example: 'Euro pallet',
21
+ description: 'Unique within the store.'
22
+ body.attribute :kind, :string,
23
+ required: true, on: :create,
24
+ choices: Spree::PackageType::KINDS,
25
+ example: 'pallet',
26
+ description: 'What this packaging is: the box parcels ship in, or the carton, pallet or container a wholesale order leaves on.'
27
+ body.attribute :length, :number, nullable: true
28
+ body.attribute :width, :number, nullable: true
29
+ body.attribute :height, :number, nullable: true
30
+ body.attribute :dimensions_unit, :string,
31
+ nullable: true,
32
+ choices: Spree::Variant::DIMENSION_UNITS,
33
+ example: 'cm',
34
+ description: "Unit the three dimensions are in; falls back to the store's unit system."
35
+ body.attribute :weight, :number,
36
+ nullable: true,
37
+ description: "The empty package's own weight, added to content weight on every quote."
38
+ body.attribute :max_weight, :number,
39
+ nullable: true,
40
+ description: 'What the package can hold, not the same as its own weight.'
41
+ body.attribute :weight_unit, :string, nullable: true, choices: Spree::Variant::WEIGHT_UNITS, example: 'kg'
42
+ body.attribute :default, :boolean,
43
+ description: 'The box every parcel quote is built on. Setting this demotes whichever row held it.'
44
+ body.attribute :metadata, :hash
45
+ end
46
+
17
47
  protected
18
48
 
19
49
  def model_class
@@ -27,11 +57,6 @@ module Spree
27
57
  def collection_includes
28
58
  [:seller]
29
59
  end
30
-
31
- def resource_permitted_attributes
32
- [:name, :kind, :length, :width, :height, :dimensions_unit,
33
- :weight, :max_weight, :weight_unit, :default, { metadata: {} }]
34
- end
35
60
  end
36
61
  end
37
62
  end
@@ -15,6 +15,23 @@ module Spree
15
15
 
16
16
  skip_before_action :authenticate_admin!
17
17
 
18
+ request_params 'PasswordResetRequestParams', action: :create do |body|
19
+ body.attribute :email, :string,
20
+ required: true,
21
+ permit: false,
22
+ format: :email,
23
+ example: 'admin@example.com'
24
+ body.attribute :redirect_url, :string,
25
+ permit: false,
26
+ example: 'https://admin.your-store.com/reset-password',
27
+ description: 'The page the emailed reset link points at, with the reset token appended. Honored only on the dashboard origin, for an account that is staff of the store; ignored otherwise.'
28
+ end
29
+
30
+ request_params 'PasswordResetParams', action: :update do |body|
31
+ body.attribute :password, :string, required: true, permit: false
32
+ body.attribute :password_confirmation, :string, required: true, permit: false
33
+ end
34
+
18
35
  # POST /api/v3/admin/password_resets
19
36
  def create
20
37
  user = Spree.admin_user_class.find_by(email: params[:email])
@@ -10,27 +10,48 @@ module Spree
10
10
  subclassed_via -> { Spree::PaymentMethod.providers },
11
11
  unknown_type_error: 'unknown_payment_method_type'
12
12
 
13
+ request_params :payment_method do |body|
14
+ body.attribute :type, :string,
15
+ required: true,
16
+ only: :create,
17
+ permit: false,
18
+ example: 'check',
19
+ description: 'Wire shorthand from the payment method types endpoint.'
20
+ body.attribute :name, :string, required: true, on: :create
21
+ body.attribute :description, :string, nullable: true
22
+ body.attribute :active, :boolean
23
+ body.attribute :storefront_visible, :boolean,
24
+ description: 'False keeps the method to the dashboard; true also offers it on the storefront.'
25
+ body.attribute :capture_method, :string,
26
+ nullable: true,
27
+ choices: Spree::CaptureMethod::CAPTURE_METHODS,
28
+ description: 'When customers are charged for this method. Null inherits the store setting.'
29
+ body.attribute :position, :integer
30
+ body.attribute :metadata, :hash
31
+ body.attribute :preferences, :hash,
32
+ description: "Values for the provider's preference schema, from the payment method types endpoint."
33
+ end
34
+
13
35
  # 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
36
+ # Returns: { data: [{ type, label, description, schema }] }.
37
+ # `schema` is the JSON Schema of the provider-specific
16
38
  # configuration fields, so admin UIs can render a generic
17
39
  # 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.
40
+ # Every provider, `installed` when the store already has one: the
41
+ # create picker leaves those out so a provider is not installed
42
+ # twice, and the edit form still finds an installed one's schema.
22
43
  def types
23
- authorize! :create, model_class
44
+ authorize! :show, model_class
24
45
 
25
46
  installed_class_names = current_store.payment_methods.pluck(:type)
26
47
  installed_shorthands = installed_class_names.filter_map do |name|
27
48
  name.safe_constantize&.api_type
28
49
  end
29
- available = model_class.subclasses_with_preference_schema.reject do |entry|
30
- installed_shorthands.include?(entry[:type])
50
+ entries = model_class.subclasses_with_preference_schema.map do |entry|
51
+ entry.merge(installed: installed_shorthands.include?(entry[:type]))
31
52
  end
32
53
 
33
- render json: { data: available }
54
+ render json: { data: entries }
34
55
  end
35
56
 
36
57
  protected
@@ -43,19 +64,14 @@ module Spree
43
64
  Spree.api.admin_payment_method_serializer
44
65
  end
45
66
 
46
- # Explicit allowlist per the v3 convention — flat params. `type` and
47
- # `preferences` are added by `SubclassedResource` on top.
48
- # Deliberately NOT routed through `normalize_params`: gateway
49
- # `preferences` are opaque provider values, and prefixed-ID resolution
50
- # recurses into nested hashes — a Stripe `webhook_endpoint_id` like
51
- # `we_1MqJ8b...` matches the prefixed-ID shape and would be decoded to
52
- # an integer. `type` and `preferences` are added by `SubclassedResource`.
67
+ # `type` is read by `SubclassedResource` from the raw params.
68
+ # Deliberately NOT routed through `normalize_params`: `metadata` holds
69
+ # opaque merchant values, and prefixed-ID resolution recurses into
70
+ # nested hashes — a value like `we_1MqJ8b...` matches the prefixed-ID
71
+ # shape and would be decoded to an integer. `preferences` decode their
72
+ # own ids from their schema.
53
73
  def permitted_params
54
- params.permit(
55
- :name, :description, :active, :storefront_visible, :auto_capture, :capture_method, :position,
56
- *model_additional_permitted_attributes,
57
- metadata: {}, preferences: {}
58
- )
74
+ params.permit(*permitted_attributes)
59
75
  end
60
76
 
61
77
  def scope
@@ -8,6 +8,14 @@ module Spree
8
8
  class PoliciesController < ResourceController
9
9
  scoped_resource :settings
10
10
 
11
+ request_params :policy do |body|
12
+ body.attribute :name, :string, required: true, on: :create, example: 'Wholesale Policy'
13
+ body.attribute :slug, :string, example: 'wholesale-policy'
14
+ body.attribute :body, :string,
15
+ nullable: true,
16
+ example: '<p>Trade orders ship within five working days.</p>'
17
+ end
18
+
11
19
  protected
12
20
 
13
21
  def model_class
@@ -18,10 +26,6 @@ module Spree
18
26
  Spree.api.admin_policy_serializer
19
27
  end
20
28
 
21
- def resource_permitted_attributes
22
- [:name, :slug, :body]
23
- end
24
-
25
29
  # Accept slug (e.g. returns-policy) or prefixed ID (e.g. pol_abc123),
26
30
  # matching the storefront's lookup.
27
31
  def find_resource
@@ -26,9 +26,35 @@ module Spree
26
26
  # actions. Wrapping it under a different name keeps both.
27
27
  before_action :load_member_resource, only: [:activate, :deactivate]
28
28
 
29
+ request_params :price_list do |body|
30
+ body.attribute :name, :string, required: true, on: :create, example: 'EU wholesale'
31
+ body.attribute :description, :string, nullable: true
32
+ body.attribute :position, :integer, example: 1
33
+ body.attribute :starts_at, :datetime,
34
+ nullable: true,
35
+ example: '2026-06-01T00:00:00Z',
36
+ description: 'Pair with `ends_at` to schedule the list: activating a list whose start is in the future marks it `scheduled`.'
37
+ body.attribute :ends_at, :datetime, nullable: true, example: '2026-09-01T00:00:00Z'
38
+ body.attribute :match_policy, :string,
39
+ choices: Spree::PriceList::MATCH_POLICIES,
40
+ example: 'all',
41
+ description: '`all`: every rule must match. `any`: one matching rule is enough.'
42
+ body.attribute :price_adjustment_percentage, :decimal,
43
+ nullable: true,
44
+ example: '-15.0',
45
+ description: 'Signed: negative discounts off base prices, positive marks up.'
46
+ body.attribute :adjust_compare_at, :boolean
47
+ body.attribute :rules, :array, of: Spree::Api::V3::Admin::PriceListRuleRequestSchema,
48
+ description: 'The complete rule set: rules are matched by `id` and updated, new ones are built, and rules left out are removed.'
49
+ body.attribute :price_adjustment_tiers, :array, of: Spree::Api::V3::Admin::PriceAdjustmentTierRequestSchema,
50
+ description: "Quantity bands on the list's percentage. The payload is the whole ladder: a band left out is removed."
51
+ body.attribute :prices, :array, of: Spree::Api::V3::Admin::PriceListPriceRequestSchema,
52
+ description: 'Per-variant price overrides. Each row upserts, so the variants it names become part of the list. Curating whole products goes through the nested products endpoint instead.'
53
+ end
54
+
29
55
  # GET /api/v3/admin/price_lists/price_rule_types
30
56
  #
31
- # Returns `[{ type, label, description, preference_schema }]`
57
+ # Returns `[{ type, label, description, schema }]`
32
58
  # for every registered subclass in `Spree.pricing.rules`. The
33
59
  # SPA uses this to build the "Add rule" picker + render a
34
60
  # generic preferences form per subclass. Rules themselves are
@@ -97,20 +123,6 @@ module Spree
97
123
  [:price_adjustment_tiers]
98
124
  end
99
125
 
100
- def permitted_params
101
- normalize_params(
102
- params.permit(
103
- *model_additional_permitted_attributes,
104
- :name, :description, :position,
105
- :starts_at, :ends_at, :match_policy,
106
- :price_adjustment_percentage, :adjust_compare_at,
107
- rules: [:id, :type, { preferences: {} }],
108
- price_adjustment_tiers: [:min_quantity, :percentage],
109
- prices: [:id, :variant_id, :currency, :min_quantity, :amount, :compare_at_amount]
110
- )
111
- )
112
- end
113
-
114
126
  private
115
127
 
116
128
  # Loads the record without the action-derived authorization