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
@@ -18,6 +18,47 @@ module Spree
18
18
 
19
19
  scoped_resource :stock
20
20
 
21
+ # The warehouses and lines are read from the raw params and resolved
22
+ # through the store (see ReceivableActions), so only the document's
23
+ # own fields are permitted.
24
+ request_params :stock_transfer do |body|
25
+ body.attribute :source_location_id, :id,
26
+ required: true, on: :create,
27
+ permit: false,
28
+ example: 'sloc_1234567890'
29
+ body.attribute :destination_location_id, :id,
30
+ required: true, on: :create,
31
+ permit: false,
32
+ example: 'sloc_1234567890'
33
+ body.attribute :reference, :string,
34
+ nullable: true,
35
+ description: "The merchant's own label for the trip. `null` clears it."
36
+ body.attribute :notes, :string, nullable: true
37
+ body.attribute :items, :array,
38
+ permit: false,
39
+ as: 'StockTransferItemParams',
40
+ description: 'A draft may open empty and gain lines as the merchant packs. Sending the list replaces whatever the draft currently holds.' do |item|
41
+ item.attribute :variant_id, :id, required: true, example: 'variant_1234567890'
42
+ item.attribute :quantity_shipped, :integer, required: true, example: 10
43
+ end
44
+ body.attribute :metadata, :hash, nullable: true
45
+ end
46
+
47
+ request_params 'StockTransferMarkInTransitParams', action: :mark_in_transit do |body|
48
+ body.attribute :force, :boolean, description: 'Ship even if it drives the source below zero.'
49
+ end
50
+
51
+ request_params 'ReceivableCloseParams', action: :close do |body|
52
+ body.attribute :reason, :string, nullable: true, description: 'Why the balance is not coming.'
53
+ end
54
+
55
+ request_params 'StockTransferCancelParams', action: :cancel do |body|
56
+ body.attribute :on_in_transit, :string,
57
+ choices: %w[restock write_off],
58
+ description: 'Required once the units have left the source: either they come back (`restock`) or they are written off as lost (`write_off`).'
59
+ body.attribute :reason, :string, nullable: true, description: 'Recorded against the written-off lines.'
60
+ end
61
+
21
62
  # The base registers this for show/update/destroy; a second
22
63
  # `before_action :set_resource` replaces that registration rather than
23
64
  # adding to it, so those three are listed again here.
@@ -129,10 +170,17 @@ module Spree
129
170
  items: items_from_params(:quantity_shipped) || [],
130
171
  reference: params[:reference],
131
172
  notes: params[:notes],
173
+ metadata: metadata_from_params,
132
174
  created_by: try_spree_current_user
133
175
  }
134
176
  end
135
177
 
178
+ # Merchant data, stored as sent: never through the prefixed-id decoding
179
+ # `permitted_params` applies.
180
+ def metadata_from_params
181
+ params.permit(*declared_permitted_attributes)[:metadata]&.to_h
182
+ end
183
+
136
184
  def update_workflow_arguments
137
185
  {
138
186
  stock_transfer: @resource,
@@ -141,13 +189,6 @@ module Spree
141
189
  }
142
190
  end
143
191
 
144
- # Only what mass assignment may safely carry. The two warehouses are
145
- # resolved through the store instead, since an id the payload names
146
- # has to be proved to belong here.
147
- def resource_permitted_attributes
148
- [:reference, :notes, { metadata: {} }]
149
- end
150
-
151
192
  # A transfer's status transitions are its own actions, so `update`
152
193
  # only ever edits the document — and its two ends are objects the
153
194
  # store handed us, never ids the payload asserted.
@@ -5,6 +5,125 @@ module Spree
5
5
  class StoreController < Admin::BaseController
6
6
  scoped_resource :settings
7
7
 
8
+ request_params :store do |body|
9
+ body.attribute :name, :string, example: 'My Store'
10
+ body.attribute :admin_locale, :string, example: 'en'
11
+ body.attribute :timezone, :string, example: 'Europe/Berlin'
12
+ body.attribute :weight_unit, :string, choices: Spree::Variant::WEIGHT_UNITS
13
+ body.attribute :unit_system, :string, choices: Spree::Store::UNIT_SYSTEMS
14
+ body.attribute :storefront_access, :string,
15
+ choices: Spree::Channel::Gating::STOREFRONT_ACCESS,
16
+ description: "The store-wide default for what anonymous visitors can see. Channels fall back to it when they don't set their own."
17
+ body.attribute :storefront_url, :string,
18
+ nullable: true,
19
+ description: "The storefront's public URL, the base for links in customer emails. Saving it also completes the storefront setup task."
20
+ body.attribute :guest_checkout, :boolean,
21
+ description: 'The store-wide default for guest checkout. Channels fall back to it.'
22
+ body.attribute :always_include_confirm_step, :boolean,
23
+ description: 'Always show a confirmation step in checkout, even when no payment method requires one.'
24
+ body.attribute :company_field_enabled, :boolean, description: 'Shows a company field on address forms.'
25
+ body.attribute :address_requires_company, :boolean,
26
+ description: 'Makes a company name mandatory on addresses.'
27
+ body.attribute :address_requires_phone, :boolean,
28
+ description: 'Makes a phone number mandatory on customer addresses.'
29
+ body.attribute :capture_method, :string,
30
+ choices: Spree::CaptureMethod::CAPTURE_METHODS,
31
+ description: "The store-wide default for when a customer is charged rather than only authorized. A payment method's own setting wins when set."
32
+ body.attribute :track_inventory_levels, :boolean,
33
+ description: 'Counts on-hand quantities. Off means everything is treated as always available.'
34
+ body.attribute :stock_reservations_enabled, :boolean,
35
+ description: "Holds stock for shoppers while they check out, so the same item can't be sold twice."
36
+ body.attribute :low_stock_threshold, :integer,
37
+ description: 'On-hand units at or below which a tracked variant counts as low stock on the home screen; 0 turns the warning off.'
38
+ body.attribute :tax_using_ship_address, :boolean,
39
+ description: 'Calculates tax from the shipping address. When false, tax is calculated from the billing address.'
40
+ body.attribute :track_price_history, :boolean,
41
+ description: 'Records price changes for the EU Omnibus lowest-price-in-30-days display.'
42
+ body.attribute :show_products_without_price, :boolean,
43
+ description: "Whether products with no price in the shopper's currency still appear in listings."
44
+ body.attribute :disable_sku_validation, :boolean,
45
+ description: 'Lets more than one variant share the same SKU.'
46
+ body.attribute :order_routing_strategy, :string,
47
+ description: 'The store-wide order routing strategy shorthand. Channels fall back to it.'
48
+ body.attribute :pricing_provider, :string,
49
+ description: 'Where prices come from: a registered provider key, or `internal`.'
50
+ body.attribute :inventory_provider, :string,
51
+ description: 'Where stock levels come from: a registered provider key, or `internal`.'
52
+ body.attribute :pricing_provider_failure_policy, :string,
53
+ choices: Spree::ProviderFailurePolicy::VALUES,
54
+ description: '`strict` refuses to price when the provider cannot answer; `fallback` uses the catalog.'
55
+ body.attribute :inventory_provider_failure_policy, :string,
56
+ choices: Spree::ProviderFailurePolicy::VALUES,
57
+ description: '`fallback` sells on the local stock snapshot when the provider cannot answer; `strict` refuses.'
58
+ body.attribute :payout_provider, :string,
59
+ description: 'Blank means the built-in provider: the marketplace settles by hand.'
60
+ body.attribute :default_payouts_schedule_interval, :string, choices: Spree::Seller::PAYOUT_INTERVALS
61
+ body.attribute :default_minimum_payout_amount, :decimal,
62
+ example: '50.00',
63
+ description: "In the store's currency."
64
+ body.attribute :auto_approve_sellers, :boolean,
65
+ description: 'Admits a seller as soon as they finish onboarding, with no operator review.'
66
+ body.attribute :auto_approve_seller_products, :boolean,
67
+ description: 'Puts a seller product on sale the moment it is submitted, with no review.'
68
+ body.attribute :send_seller_transactional_emails, :boolean,
69
+ description: 'When false, transactional seller emails (approval, payouts and so on) are not sent.'
70
+ body.attribute :default_commission_tax_rate, :decimal,
71
+ example: '0.23',
72
+ description: 'Tax charged on commission as a fraction (`"0.23"` is 23%), when neither the commission rate nor the tax provider names one.'
73
+ body.attribute :document_number_format, :string,
74
+ example: 'sequential',
75
+ description: 'How document numbers are produced: `sequential` or `random`. Applies to every numbered document.'
76
+ body.attribute :order_number_prefix, :string,
77
+ example: 'R',
78
+ description: 'Leads every order number. Uppercase letters, digits, dashes and # only.'
79
+ body.attribute :order_number_suffix, :string,
80
+ description: 'Ends every order number. Uppercase letters, digits, dashes and # only.'
81
+ body.attribute :order_number_sequence_start, :integer,
82
+ description: "The first sequential order number. Only applies before the store's first order."
83
+ body.attribute :limit_digital_download_count, :boolean,
84
+ description: 'Whether a digital download link stops working after a number of clicks.'
85
+ body.attribute :digital_asset_authorized_clicks, :integer,
86
+ description: 'How many clicks a download link allows, unless the file sets its own.'
87
+ body.attribute :limit_digital_download_days, :boolean,
88
+ description: 'Whether a digital download link expires after a number of days.'
89
+ body.attribute :digital_asset_authorized_days, :integer,
90
+ description: 'How many days a download link stays valid, unless the file sets its own.'
91
+ body.attribute :mail_from_address, :string, description: 'Sender address of every transactional email.'
92
+ body.attribute :customer_support_email, :string,
93
+ nullable: true,
94
+ description: 'Customer-facing reply-to address shown in the storefront and email footers.'
95
+ body.attribute :new_order_notifications_email, :string,
96
+ nullable: true,
97
+ description: 'Recipient of "new order placed" staff notifications.'
98
+ body.attribute :send_consumer_transactional_emails, :boolean,
99
+ description: 'When false, transactional customer emails (order confirmation and so on) are not sent.'
100
+ body.attribute :email_accent_color, :string,
101
+ nullable: true,
102
+ description: 'Customer email buttons and links, as `#RRGGBB`. Blank keeps the outlined buttons emails ship with.'
103
+ body.attribute :email_background_color, :string,
104
+ nullable: true,
105
+ description: 'Customer email page background, as `#RRGGBB`.'
106
+ body.attribute :email_card_color, :string,
107
+ nullable: true,
108
+ description: 'Customer email card behind the content, as `#RRGGBB`.'
109
+ body.attribute :email_text_color, :string,
110
+ nullable: true,
111
+ description: 'Customer email body text, as `#RRGGBB`.'
112
+ body.attribute :email_heading_color, :string,
113
+ nullable: true,
114
+ description: 'Customer email headings and emphasized text, as `#RRGGBB`.'
115
+ body.attribute :email_font, :string,
116
+ nullable: true,
117
+ example: 'inter',
118
+ description: 'Customer email font: `inter`, `system`, `helvetica`, `georgia`, `roboto`, `lato` or `merriweather`.'
119
+ body.attribute :logo_signed_id, :string,
120
+ nullable: true,
121
+ description: 'A `signed_id` from `files.upload()` for the store logo, or null to remove it.'
122
+ body.attribute :mailer_logo_signed_id, :string,
123
+ nullable: true,
124
+ description: 'A `signed_id` from `files.upload()` for the logo in transactional emails, or null to remove it.'
125
+ end
126
+
8
127
  # Reading the current store is shell data — the dashboard needs the
9
128
  # name, logo, timezone, currency and locales to render anything at
10
129
  # all, so every signed-in staff member can read it regardless of
@@ -70,60 +189,10 @@ module Spree
70
189
  Spree.api.admin_store_serializer
71
190
  end
72
191
 
192
+ # Extensions' fields too: the store settings page saves the fields
193
+ # plugins add to it with the rest of the form.
73
194
  def permitted_params
74
- params.permit(
75
- :name,
76
- :preferred_admin_locale,
77
- :preferred_timezone,
78
- :preferred_weight_unit,
79
- :preferred_unit_system,
80
- :preferred_storefront_access,
81
- :preferred_storefront_url,
82
- :preferred_guest_checkout,
83
- :preferred_always_include_confirm_step,
84
- :preferred_company_field_enabled,
85
- :preferred_address_requires_company,
86
- :preferred_address_requires_phone,
87
- :preferred_capture_method,
88
- # @deprecated Superseded by preferred_capture_method; the model
89
- # maps them onto it. Removed in 6.1.
90
- :preferred_auto_capture,
91
- :preferred_auto_capture_on_dispatch,
92
- :preferred_track_inventory_levels,
93
- :preferred_stock_reservations_enabled,
94
- :preferred_low_stock_threshold,
95
- :preferred_tax_using_ship_address,
96
- :preferred_track_price_history,
97
- :preferred_show_products_without_price,
98
- :preferred_disable_sku_validation,
99
- :preferred_order_routing_strategy,
100
- :preferred_pricing_provider,
101
- :preferred_inventory_provider,
102
- :preferred_pricing_provider_failure_policy,
103
- :preferred_inventory_provider_failure_policy,
104
- :preferred_payout_provider,
105
- :preferred_default_payouts_schedule_interval,
106
- :preferred_default_minimum_payout_amount,
107
- :preferred_auto_approve_sellers,
108
- :preferred_auto_approve_seller_products,
109
- :preferred_send_seller_transactional_emails,
110
- :preferred_default_commission_tax_rate,
111
- :preferred_document_number_format,
112
- :preferred_order_number_prefix,
113
- :preferred_order_number_suffix,
114
- :preferred_order_number_sequence_start,
115
- :mail_from_address,
116
- :customer_support_email,
117
- :new_order_notifications_email,
118
- :preferred_send_consumer_transactional_emails,
119
- :preferred_email_accent_color,
120
- :preferred_email_background_color,
121
- :preferred_email_card_color,
122
- :preferred_email_text_color,
123
- :preferred_email_heading_color,
124
- :preferred_email_font,
125
- :mailer_logo
126
- )
195
+ params.permit(*declared_permitted_attributes, *Array(Spree::Store.additional_permitted_attributes))
127
196
  end
128
197
  end
129
198
  end
@@ -63,9 +63,6 @@ module Spree
63
63
  )
64
64
 
65
65
  rows.map do |currency, amount, used, authorized|
66
- # `SUM` answers an Integer on a whole-number total, and these
67
- # totals render beside rows that serialize decimal strings — so
68
- # "50" must not appear against their "50.0".
69
66
  figures = {
70
67
  amount: amount.to_d,
71
68
  amount_used: used.to_d,
@@ -74,10 +71,7 @@ module Spree
74
71
  figures[:amount_remaining] =
75
72
  figures[:amount] - figures[:amount_used] - figures[:amount_authorized]
76
73
 
77
- displays = figures.transform_keys { |name| :"display_#{name}" }.
78
- transform_values { |value| Spree::Money.new(value, currency: currency).to_s }
79
-
80
- { currency: currency }.merge(figures.transform_values(&:to_s)).merge(displays)
74
+ { currency: currency }.merge(figures.transform_values { |value| Spree::Money::Rounding.format(value, currency) })
81
75
  end
82
76
  end
83
77
  end
@@ -8,6 +8,22 @@ module Spree
8
8
  class SuppliersController < ResourceController
9
9
  scoped_resource :purchasing
10
10
 
11
+ request_params :supplier do |body|
12
+ body.attribute :name, :string, required: true, on: :create, example: 'Northwind Trading'
13
+ body.attribute :contact_name, :string, nullable: true, example: 'Dana Okafor'
14
+ body.attribute :email, :string, nullable: true, example: 'sales@northwind.test'
15
+ body.attribute :phone, :string, nullable: true, example: '555-0100'
16
+ body.attribute :notes, :string, nullable: true
17
+ body.attribute :address1, :string, nullable: true, example: '1 Warehouse Way'
18
+ body.attribute :address2, :string, nullable: true
19
+ body.attribute :city, :string, nullable: true, example: 'Brooklyn'
20
+ body.attribute :state_name, :string, nullable: true
21
+ body.attribute :state_code, :string, nullable: true, example: 'NY'
22
+ body.attribute :country_code, :country, nullable: true, example: 'US'
23
+ body.attribute :postal_code, :string, nullable: true, example: '11201'
24
+ body.attribute :metadata, :hash, nullable: true
25
+ end
26
+
11
27
  protected
12
28
 
13
29
  def model_class
@@ -17,12 +33,6 @@ module Spree
17
33
  def serializer_class
18
34
  Spree.api.admin_supplier_serializer
19
35
  end
20
-
21
- def resource_permitted_attributes
22
- [:name, :contact_name, :email, :phone, :notes,
23
- :address1, :address2, :city, :state_name, :state_code,
24
- :country_code, :postal_code, { metadata: {} }]
25
- end
26
36
  end
27
37
  end
28
38
  end
@@ -5,6 +5,13 @@ module Spree
5
5
  class TaxCategoriesController < ResourceController
6
6
  scoped_resource :settings
7
7
 
8
+ request_params :tax_category do |body|
9
+ body.attribute :name, :string, required: true, on: :create
10
+ body.attribute :tax_code, :string, nullable: true
11
+ body.attribute :description, :string, nullable: true
12
+ body.attribute :is_default, :boolean
13
+ end
14
+
8
15
  protected
9
16
 
10
17
  def model_class
@@ -14,10 +21,6 @@ module Spree
14
21
  def serializer_class
15
22
  Spree.api.admin_tax_category_serializer
16
23
  end
17
-
18
- def resource_permitted_attributes
19
- [:name, :tax_code, :description, :is_default]
20
- end
21
24
  end
22
25
  end
23
26
  end
@@ -7,6 +7,26 @@ module Spree
7
7
  class TaxRatesController < ResourceController
8
8
  scoped_resource :settings
9
9
 
10
+ request_params :tax_rate do |body|
11
+ body.attribute :name, :string, required: true, on: :create, example: 'VAT', description: 'Customer-facing rate name.'
12
+ body.attribute :rate, :decimal,
13
+ example: '0.19',
14
+ description: 'The rate as a fraction. Send this or `rate_percent`.'
15
+ body.attribute :rate_percent, :decimal, example: '19', description: 'The rate as a percentage.'
16
+ body.attribute :included_in_price, :boolean
17
+ body.attribute :show_rate_in_label, :boolean
18
+ body.attribute :tax_category_id, :id, required: true, on: :create
19
+ body.attribute :country_code, :country,
20
+ nullable: true,
21
+ example: 'DE',
22
+ description: 'ISO country code. A rate naming no country taxes everywhere.'
23
+ body.attribute :state_code, :string,
24
+ nullable: true,
25
+ example: 'CA',
26
+ description: 'State abbreviation within that country.'
27
+ body.attribute :metadata, :hash
28
+ end
29
+
10
30
  protected
11
31
 
12
32
  def model_class
@@ -22,9 +42,7 @@ module Spree
22
42
  end
23
43
 
24
44
  def permitted_params
25
- params.permit(*model_additional_permitted_attributes, :name, :amount, :amount_percentage, :included_in_price,
26
- :show_rate_in_label, :tax_category_id,
27
- :country_code, :state_code, metadata: {})
45
+ params.permit(*permitted_attributes)
28
46
  end
29
47
  end
30
48
  end
@@ -23,6 +23,10 @@ module Spree
23
23
 
24
24
  protected
25
25
 
26
+ def filterable?
27
+ false
28
+ end
29
+
26
30
  def model_class
27
31
  Spree::Fulfillment
28
32
  end
@@ -13,15 +13,6 @@ module Spree
13
13
  # resource_type + resource_id, so the controller stays free of
14
14
  # per-model branching.
15
15
  #
16
- # POST /api/v3/admin/translations/batch
17
- # Body:
18
- # { "translations": [
19
- # { "resource_type": "option_type", "resource_id": "opt_…",
20
- # "values": { "de": { "label": "Größe" } } },
21
- # { "resource_type": "option_value", "resource_id": "optval_…",
22
- # "values": { "de": { "label": "Klein" } } }
23
- # ] }
24
- #
25
16
  # All entries succeed or none do — a validation failure on any entry
26
17
  # rolls back the whole transaction and returns per-entry detail.
27
18
  # The orchestration (resolve → upsert → rollback) lives in
@@ -34,6 +25,23 @@ module Spree
34
25
  # which is stricter than the static check and keeps the audit model.
35
26
  skip_scope_check!
36
27
 
28
+ request_params 'TranslationBatchParams' do |body|
29
+ body.attribute :translations, :array,
30
+ required: true,
31
+ as: 'TranslationBatchEntryParams',
32
+ description: 'At least one entry. All entries are saved, or none are.' do |translation|
33
+ translation.attribute :resource_type, :string,
34
+ required: true,
35
+ example: 'option_type',
36
+ description: 'Translatable resource type token, e.g. `option_type`.'
37
+ translation.attribute :resource_id, :id, required: true, example: 'opt_abc123'
38
+ translation.attribute :values, :hash,
39
+ required: true,
40
+ example: { de: { label: 'Größe' } },
41
+ description: 'Translated fields keyed by locale code, then by field name.'
42
+ end
43
+ end
44
+
37
45
  # POST /api/v3/admin/translations/batch
38
46
  def create
39
47
  raw = params[:translations]
@@ -29,6 +29,10 @@ module Spree
29
29
 
30
30
  protected
31
31
 
32
+ def filterable?
33
+ false
34
+ end
35
+
32
36
  def set_parent
33
37
  raise ActiveRecord::RecordNotFound, 'Parent resource not found' unless parent_lookup
34
38
 
@@ -31,6 +31,11 @@ module Spree
31
31
 
32
32
  protected
33
33
 
34
+ # The model, and so the filters, follow `resource_type`.
35
+ def filterable?
36
+ false
37
+ end
38
+
34
39
  # Resolved from the required `resource_type` param. An unknown or
35
40
  # untranslatable type is a 404 rather than a 500 from a nil class.
36
41
  def model_class
@@ -0,0 +1,39 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # Whether a newer Spree release exists, for the dashboard's update
6
+ # notice. Asks spreecloud.io at most once a day (see Spree::UpdateCheck).
7
+ #
8
+ # The only place the Admin API reveals the running Spree version, so it
9
+ # answers signed-in staff who can manage the store and nobody else. A
10
+ # secret API key gets a 404, like GET /me: an integration key would
11
+ # otherwise fingerprint the deployment for anyone matching CVEs.
12
+ class UpdatesController < Admin::BaseController
13
+ skip_scope_check!
14
+
15
+ before_action :require_current_user!
16
+
17
+ # GET /api/v3/admin/updates
18
+ def show
19
+ authorize! :manage, current_store
20
+
21
+ render json: Spree.api.admin_update_status_serializer.new(Spree::UpdateCheck.status).to_h
22
+ end
23
+
24
+ private
25
+
26
+ def require_current_user!
27
+ return if current_user
28
+
29
+ render_error(
30
+ code: ERROR_CODES[:record_not_found],
31
+ message: I18n.t('spree.me_no_current_user'),
32
+ status: :not_found
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -8,6 +8,28 @@ module Spree
8
8
  class WebhookEndpointsController < ResourceController
9
9
  scoped_resource :webhooks
10
10
 
11
+ request_params :webhook_endpoint do |body|
12
+ body.attribute :name, :string,
13
+ nullable: true,
14
+ example: 'Order pipeline',
15
+ description: 'A label shown in the dashboard list.'
16
+ body.attribute :url, :string,
17
+ required: true, on: :create,
18
+ example: 'https://example.com/webhooks/orders',
19
+ description: 'HTTPS destination URL. It cannot resolve to a private IP address outside development.'
20
+ body.attribute :active, :boolean,
21
+ description: 'Defaults to true on create. Prefer the disable and enable endpoints to pause one.'
22
+ body.attribute :subscriptions, :array, of: :string,
23
+ example: %w[order.placed order.canceled],
24
+ description: 'Event names this endpoint receives. An empty list or `["*"]` subscribes to every event; otherwise list exact names (`order.completed`) or patterns (`order.*`).'
25
+ end
26
+
27
+ request_params 'WebhookEndpointDisableParams', action: :disable do |body|
28
+ body.attribute :reason, :string,
29
+ example: 'Investigating elevated 5xx rate',
30
+ description: 'Shown next to the disabled indicator. Defaults to "Manually disabled".'
31
+ end
32
+
11
33
  before_action :reject_unauthorized_credential_subscription!, only: [:create, :update]
12
34
 
13
35
  # POST /api/v3/admin/webhook_endpoints/:id/send_test
@@ -68,7 +90,7 @@ module Spree
68
90
  end
69
91
 
70
92
  def permitted_params
71
- params.permit(*model_additional_permitted_attributes, :name, :url, :active, subscriptions: [])
93
+ params.permit(*permitted_attributes)
72
94
  end
73
95
 
74
96
  private
@@ -12,6 +12,8 @@ module Spree
12
12
  include Spree::Api::V3::JwtAuthentication
13
13
  include Spree::Api::V3::ApiKeyAuthentication
14
14
  include Spree::Api::V3::ErrorHandler
15
+ include Spree::Api::V3::MoneyParams
16
+ include Spree::Api::V3::RequestParams
15
17
  include Spree::Api::V3::SecurityHeaders
16
18
  include Spree::Api::V3::ResourceSerializer
17
19
  include Spree::Api::V3::RateLimitHeaders
@@ -96,6 +96,18 @@ module Spree
96
96
 
97
97
  protected
98
98
 
99
+ # Runs the block's assignments and saves the resource as one unit:
100
+ # assigning a has_one (a calculator, say) on a saved record writes it
101
+ # at once, so anything refused afterwards rolls that back too.
102
+ #
103
+ # @return [Boolean] whether the resource was saved
104
+ def save_atomically
105
+ model_class.transaction do
106
+ yield
107
+ @resource.save || raise(ActiveRecord::Rollback)
108
+ end || false
109
+ end
110
+
99
111
  def authenticate_request!
100
112
  raise NotImplementedError, "#{self.class} must implement authenticate_request!"
101
113
  end
@@ -272,6 +284,32 @@ module Spree
272
284
  nil
273
285
  end
274
286
 
287
+ # Whether this endpoint's list filters through Ransack on
288
+ # {#model_class}. An index that ignores `q`, or whose model depends on
289
+ # the request, has no filter table to publish.
290
+ #
291
+ # @return [Boolean]
292
+ def filterable?
293
+ true
294
+ end
295
+
296
+ # Sort keys this endpoint accepts beyond the model's sortable
297
+ # attributes, for a controller that sorts outside Ransack.
298
+ #
299
+ # @return [Array<String>]
300
+ def additional_sort_fields
301
+ []
302
+ end
303
+
304
+ # Whether this endpoint also filters and sorts on the store's
305
+ # searchable custom fields (`cf_<namespace>_<key>`), which are store
306
+ # data and so cannot be listed in the contract.
307
+ #
308
+ # @return [Boolean]
309
+ def custom_field_filters?
310
+ false
311
+ end
312
+
275
313
  # Override in subclass to disable distinct (e.g., for custom sorting with computed columns)
276
314
  # @return [Boolean] whether to apply distinct to the collection
277
315
  def collection_distinct?
@@ -360,15 +398,27 @@ module Spree
360
398
  end
361
399
  end
362
400
 
363
- # @param attribute [String, nil] a `*type` column of {#model_class}
401
+ # A `*type` column of {#model_class}, or of a model it reaches through
402
+ # its associations (`payment_method_type`), as the filter tables publish.
403
+ #
404
+ # @param attribute [String, nil]
364
405
  # @return [Proc, nil] shorthand → stored class name
365
- def api_type_resolver(attribute)
366
- return if attribute.nil? || !model_class.respond_to?(:api_type_registry)
367
-
368
- if attribute == model_class.inheritance_column && model_class.api_type_registry.any?
369
- ->(api_type) { model_class.class_name_for_api_type(api_type) }
370
- elsif model_class.reflect_on_all_associations(:belongs_to).any? { |reflection| reflection.polymorphic? && reflection.foreign_type == attribute }
371
- ->(api_type) { Spree::Base.polymorphic_type_for(api_type) }
406
+ def api_type_resolver(attribute, model = model_class, depth = 0)
407
+ return if attribute.nil? || !model.respond_to?(:api_type_resolver)
408
+
409
+ model.api_type_resolver(attribute) || begin
410
+ return if depth >= Spree::Api::V3::FilterTable::MAX_DEPTH
411
+
412
+ model.reflect_on_all_associations.each do |reflection|
413
+ next if reflection.polymorphic? || !attribute.start_with?("#{reflection.name}_")
414
+
415
+ resolver = api_type_resolver(attribute.delete_prefix("#{reflection.name}_"), reflection.klass, depth + 1)
416
+ return resolver if resolver
417
+ rescue NameError
418
+ # A reflection naming a class this installation does not load.
419
+ next
420
+ end
421
+ nil
372
422
  end
373
423
  end
374
424
 
@@ -511,9 +561,12 @@ module Spree
511
561
  resource_permitted_attributes + model_additional_permitted_attributes
512
562
  end
513
563
 
514
- # Override in subclass to declare the resource's writable attributes.
564
+ # The resource's writable attributes: its `request_params`
565
+ # declaration, or an override in the subclass.
515
566
  def resource_permitted_attributes
516
- raise NotImplementedError, 'Subclass must implement resource_permitted_attributes or permitted_params'
567
+ return declared_permitted_attributes if request_params_schema
568
+
569
+ raise NotImplementedError, 'Subclass must declare request_params, or implement resource_permitted_attributes or permitted_params'
517
570
  end
518
571
 
519
572
  # Attributes extensions have declared on the model via