spree_api 6.0.0.rc1 → 6.0.0.rc3

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 (371) 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/store/search_provider_support.rb +8 -3
  23. data/app/controllers/concerns/spree/api/v3/strict_money_params.rb +94 -0
  24. data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +10 -1
  25. data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +8 -1
  26. data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +15 -7
  27. data/app/controllers/spree/api/v3/admin/base_controller.rb +1 -0
  28. data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +3 -1
  29. data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +7 -5
  30. data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +60 -33
  31. data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +4 -1
  32. data/app/controllers/spree/api/v3/admin/categories_controller.rb +40 -20
  33. data/app/controllers/spree/api/v3/admin/channels_controller.rb +39 -6
  34. data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +5 -1
  35. data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +4 -1
  36. data/app/controllers/spree/api/v3/admin/collections_controller.rb +44 -15
  37. data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +60 -12
  38. data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +11 -0
  39. data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +9 -1
  40. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +19 -18
  41. data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +6 -1
  42. data/app/controllers/spree/api/v3/admin/companies_controller.rb +17 -3
  43. data/app/controllers/spree/api/v3/admin/countries_controller.rb +5 -1
  44. data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +21 -11
  45. data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +12 -5
  46. data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +9 -1
  47. data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +12 -7
  48. data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +11 -9
  49. data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +6 -1
  50. data/app/controllers/spree/api/v3/admin/customers_controller.rb +35 -7
  51. data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +8 -0
  52. data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +1 -1
  53. data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +15 -7
  54. data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +92 -57
  55. data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +8 -1
  56. data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +13 -1
  57. data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +21 -5
  58. data/app/controllers/spree/api/v3/admin/email_templates/drafts_controller.rb +14 -1
  59. data/app/controllers/spree/api/v3/admin/email_templates/previews_controller.rb +4 -0
  60. data/app/controllers/spree/api/v3/admin/email_templates/publications_controller.rb +7 -0
  61. data/app/controllers/spree/api/v3/admin/email_templates/restorations_controller.rb +8 -0
  62. data/app/controllers/spree/api/v3/admin/email_templates/test_emails_controller.rb +4 -0
  63. data/app/controllers/spree/api/v3/admin/exports_controller.rb +23 -6
  64. data/app/controllers/spree/api/v3/admin/files_controller.rb +29 -0
  65. data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +20 -1
  66. data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +19 -1
  67. data/app/controllers/spree/api/v3/admin/imports_controller.rb +36 -9
  68. data/app/controllers/spree/api/v3/admin/integrations_controller.rb +13 -1
  69. data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +9 -2
  70. data/app/controllers/spree/api/v3/admin/invitations_controller.rb +8 -1
  71. data/app/controllers/spree/api/v3/admin/locales_controller.rb +1 -1
  72. data/app/controllers/spree/api/v3/admin/markets_controller.rb +30 -9
  73. data/app/controllers/spree/api/v3/admin/me_controller.rb +12 -3
  74. data/app/controllers/spree/api/v3/admin/media_controller.rb +22 -9
  75. data/app/controllers/spree/api/v3/admin/media_library_controller.rb +4 -0
  76. data/app/controllers/spree/api/v3/admin/option_types_controller.rb +24 -7
  77. data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +5 -1
  78. data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +13 -1
  79. data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +39 -1
  80. data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +19 -1
  81. data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +5 -1
  82. data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +29 -5
  83. data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +36 -1
  84. data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +22 -1
  85. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +66 -7
  86. data/app/controllers/spree/api/v3/admin/orders/gift_cards_controller.rb +6 -2
  87. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +11 -1
  88. data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +35 -2
  89. data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +16 -5
  90. data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +6 -0
  91. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +37 -1
  92. data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +6 -3
  93. data/app/controllers/spree/api/v3/admin/orders_controller.rb +74 -60
  94. data/app/controllers/spree/api/v3/admin/package_types_controller.rb +30 -5
  95. data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +17 -0
  96. data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +38 -22
  97. data/app/controllers/spree/api/v3/admin/policies_controller.rb +8 -4
  98. data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +27 -15
  99. data/app/controllers/spree/api/v3/admin/prices_controller.rb +51 -4
  100. data/app/controllers/spree/api/v3/admin/product_types_controller.rb +25 -8
  101. data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +27 -10
  102. data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +9 -14
  103. data/app/controllers/spree/api/v3/admin/products_controller.rb +121 -70
  104. data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +11 -2
  105. data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +10 -1
  106. data/app/controllers/spree/api/v3/admin/promotions_controller.rb +50 -14
  107. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +54 -7
  108. data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +5 -1
  109. data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +9 -1
  110. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +34 -0
  111. data/app/controllers/spree/api/v3/admin/resource_controller.rb +1 -0
  112. data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +5 -1
  113. data/app/controllers/spree/api/v3/admin/roles_controller.rb +13 -1
  114. data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +6 -0
  115. data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +15 -0
  116. data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +32 -6
  117. data/app/controllers/spree/api/v3/admin/sellers_controller.rb +75 -22
  118. data/app/controllers/spree/api/v3/admin/setup_controller.rb +54 -15
  119. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +38 -9
  120. data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +41 -9
  121. data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +48 -7
  122. data/app/controllers/spree/api/v3/admin/store_controller.rb +122 -53
  123. data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +1 -7
  124. data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +16 -6
  125. data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +7 -4
  126. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +21 -3
  127. data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +4 -0
  128. data/app/controllers/spree/api/v3/admin/translations/batches_controller.rb +17 -9
  129. data/app/controllers/spree/api/v3/admin/translations_controller.rb +4 -0
  130. data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +5 -0
  131. data/app/controllers/spree/api/v3/admin/updates_controller.rb +39 -0
  132. data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +23 -1
  133. data/app/controllers/spree/api/v3/base_controller.rb +2 -0
  134. data/app/controllers/spree/api/v3/resource_controller.rb +63 -10
  135. data/app/controllers/spree/api/v3/seller/auth_controller.rb +8 -0
  136. data/app/controllers/spree/api/v3/seller/base_controller.rb +1 -0
  137. data/app/controllers/spree/api/v3/seller/countries_controller.rb +2 -2
  138. data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +49 -60
  139. data/app/controllers/spree/api/v3/seller/exports_controller.rb +18 -1
  140. data/app/controllers/spree/api/v3/seller/files_controller.rb +27 -0
  141. data/app/controllers/spree/api/v3/seller/imports_controller.rb +25 -9
  142. data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +9 -1
  143. data/app/controllers/spree/api/v3/seller/me_controller.rb +14 -3
  144. data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +11 -0
  145. data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +35 -0
  146. data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +12 -0
  147. data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +33 -0
  148. data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +28 -2
  149. data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +22 -1
  150. data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +8 -1
  151. data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +32 -0
  152. data/app/controllers/spree/api/v3/seller/orders_controller.rb +35 -14
  153. data/app/controllers/spree/api/v3/seller/package_types_controller.rb +21 -9
  154. data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +10 -0
  155. data/app/controllers/spree/api/v3/seller/policies_controller.rb +12 -4
  156. data/app/controllers/spree/api/v3/seller/products_controller.rb +114 -28
  157. data/app/controllers/spree/api/v3/seller/profile_controller.rb +33 -10
  158. data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +12 -5
  159. data/app/controllers/spree/api/v3/seller/resource_controller.rb +12 -0
  160. data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +44 -13
  161. data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +10 -1
  162. data/app/controllers/spree/api/v3/seller/team_controller.rb +4 -0
  163. data/app/controllers/spree/api/v3/store/auth_controller.rb +10 -0
  164. data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +8 -1
  165. data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +10 -2
  166. data/app/controllers/spree/api/v3/store/carts/gift_cards_controller.rb +8 -1
  167. data/app/controllers/spree/api/v3/store/carts/items_controller.rb +17 -5
  168. data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +20 -6
  169. data/app/controllers/spree/api/v3/store/carts/payments_controller.rb +11 -0
  170. data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +24 -26
  171. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +19 -1
  172. data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +5 -1
  173. data/app/controllers/spree/api/v3/store/carts_controller.rb +54 -47
  174. data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +12 -4
  175. data/app/controllers/spree/api/v3/store/companies/members_controller.rb +4 -0
  176. data/app/controllers/spree/api/v3/store/companies_controller.rb +5 -1
  177. data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +9 -1
  178. data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +8 -7
  179. data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +5 -0
  180. data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +17 -0
  181. data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +10 -5
  182. data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +5 -1
  183. data/app/controllers/spree/api/v3/store/customers_controller.rb +28 -2
  184. data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +22 -0
  185. data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +11 -2
  186. data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +10 -1
  187. data/app/controllers/spree/api/v3/store/orders_controller.rb +47 -10
  188. data/app/controllers/spree/api/v3/store/products_controller.rb +8 -0
  189. data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +10 -4
  190. data/app/controllers/spree/api/v3/store/wishlists_controller.rb +12 -4
  191. data/app/request_schemas/spree/api/v3/address_request_schema.rb +27 -0
  192. data/app/request_schemas/spree/api/v3/admin/address_request_schema.rb +13 -0
  193. data/app/request_schemas/spree/api/v3/admin/bulk_tags_request_schema.rb +17 -0
  194. data/app/request_schemas/spree/api/v3/admin/catalog_order_minimum_request_schema.rb +17 -0
  195. data/app/request_schemas/spree/api/v3/admin/email_template_language_request_schema.rb +17 -0
  196. data/app/request_schemas/spree/api/v3/admin/email_template_preview_request_schema.rb +32 -0
  197. data/app/request_schemas/spree/api/v3/admin/price_adjustment_tier_request_schema.rb +21 -0
  198. data/app/request_schemas/spree/api/v3/admin/price_list_price_request_schema.rb +21 -0
  199. data/app/request_schemas/spree/api/v3/admin/price_list_rule_request_schema.rb +19 -0
  200. data/app/request_schemas/spree/api/v3/admin/product_membership_reposition_request_schema.rb +17 -0
  201. data/app/request_schemas/spree/api/v3/admin/promotion_action_calculator_request_schema.rb +18 -0
  202. data/app/request_schemas/spree/api/v3/admin/promotion_action_line_item_request_schema.rb +15 -0
  203. data/app/request_schemas/spree/api/v3/admin/promotion_action_request_schema.rb +19 -0
  204. data/app/request_schemas/spree/api/v3/admin/promotion_rule_request_schema.rb +22 -0
  205. data/app/request_schemas/spree/api/v3/admin/reason_request_schema.rb +14 -0
  206. data/app/request_schemas/spree/api/v3/admin/tax_identifier_request_schema.rb +15 -0
  207. data/app/request_schemas/spree/api/v3/custom_field_value_request_schema.rb +15 -0
  208. data/app/request_schemas/spree/api/v3/file_upload_request_schema.rb +20 -0
  209. data/app/request_schemas/spree/api/v3/media_request_schema.rb +27 -0
  210. data/app/request_schemas/spree/api/v3/price_request_schema.rb +17 -0
  211. data/app/request_schemas/spree/api/v3/stock_level_request_schema.rb +18 -0
  212. data/app/request_schemas/spree/api/v3/store/address_request_schema.rb +31 -0
  213. data/app/request_schemas/spree/api/v3/tax_identifier_request_schema.rb +18 -0
  214. data/app/request_schemas/spree/api/v3/variant_option_request_schema.rb +13 -0
  215. data/app/request_schemas/spree/api/v3/variant_request_schema.rb +52 -0
  216. data/app/serializers/concerns/spree/api/v3/purchase_summary.rb +48 -0
  217. data/app/serializers/spree/api/v3/address_serializer.rb +4 -2
  218. data/app/serializers/spree/api/v3/admin/address_serializer.rb +3 -0
  219. data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +3 -1
  220. data/app/serializers/spree/api/v3/admin/cart_serializer.rb +3 -1
  221. data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +3 -2
  222. data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +3 -4
  223. data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +4 -3
  224. data/app/serializers/spree/api/v3/admin/channel_serializer.rb +5 -7
  225. data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +7 -0
  226. data/app/serializers/spree/api/v3/admin/claim_serializer.rb +5 -0
  227. data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +7 -18
  228. data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +7 -11
  229. data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +0 -2
  230. data/app/serializers/spree/api/v3/admin/country_serializer.rb +4 -0
  231. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +3 -7
  232. data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +0 -2
  233. data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +14 -10
  234. data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +9 -1
  235. data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +8 -0
  236. data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -1
  237. data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +5 -0
  238. data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +5 -0
  239. data/app/serializers/spree/api/v3/admin/fee_serializer.rb +3 -1
  240. data/app/serializers/spree/api/v3/admin/file_upload_serializer.rb +11 -0
  241. data/app/serializers/spree/api/v3/admin/file_upload_target_serializer.rb +10 -0
  242. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +13 -11
  243. data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +3 -3
  244. data/app/serializers/spree/api/v3/admin/import_serializer.rb +2 -2
  245. data/app/serializers/spree/api/v3/admin/integration_serializer.rb +1 -3
  246. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +12 -12
  247. data/app/serializers/spree/api/v3/admin/locale_serializer.rb +13 -0
  248. data/app/serializers/spree/api/v3/admin/market_serializer.rb +3 -0
  249. data/app/serializers/spree/api/v3/admin/media_serializer.rb +3 -2
  250. data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +2 -0
  251. data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +1 -3
  252. data/app/serializers/spree/api/v3/admin/order_serializer.rb +33 -33
  253. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +1 -4
  254. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -3
  255. data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +8 -9
  256. data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +3 -6
  257. data/app/serializers/spree/api/v3/admin/price_history_serializer.rb +6 -2
  258. data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +1 -5
  259. data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +1 -3
  260. data/app/serializers/spree/api/v3/admin/price_serializer.rb +4 -0
  261. data/app/serializers/spree/api/v3/admin/product_serializer.rb +2 -0
  262. data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +4 -6
  263. data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +0 -2
  264. data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +5 -11
  265. data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +4 -4
  266. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +7 -3
  267. data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +9 -2
  268. data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +8 -0
  269. data/app/serializers/spree/api/v3/admin/return_serializer.rb +8 -4
  270. data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +15 -10
  271. data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +3 -5
  272. data/app/serializers/spree/api/v3/admin/seller_serializer.rb +3 -1
  273. data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +7 -8
  274. data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +4 -4
  275. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +3 -0
  276. data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +2 -6
  277. data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +5 -0
  278. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +9 -4
  279. data/app/serializers/spree/api/v3/admin/store_serializer.rb +17 -98
  280. data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +1 -1
  281. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +3 -1
  282. data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +4 -2
  283. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +2 -12
  284. data/app/serializers/spree/api/v3/admin/update_status_serializer.rb +28 -0
  285. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +7 -3
  286. data/app/serializers/spree/api/v3/base_serializer.rb +112 -7
  287. data/app/serializers/spree/api/v3/cart_serializer.rb +16 -30
  288. data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +5 -13
  289. data/app/serializers/spree/api/v3/claim_serializer.rb +2 -3
  290. data/app/serializers/spree/api/v3/country_serializer.rb +2 -1
  291. data/app/serializers/spree/api/v3/currency_serializer.rb +9 -1
  292. data/app/serializers/spree/api/v3/customer_serializer.rb +3 -2
  293. data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +8 -12
  294. data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +1 -1
  295. data/app/serializers/spree/api/v3/discount_serializer.rb +4 -1
  296. data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +2 -8
  297. data/app/serializers/spree/api/v3/exchange_serializer.rb +2 -3
  298. data/app/serializers/spree/api/v3/file_upload_serializer.rb +28 -0
  299. data/app/serializers/spree/api/v3/file_upload_target_serializer.rb +17 -0
  300. data/app/serializers/spree/api/v3/gift_card_batch_serializer.rb +2 -4
  301. data/app/serializers/spree/api/v3/gift_card_serializer.rb +4 -2
  302. data/app/serializers/spree/api/v3/import_serializer.rb +0 -12
  303. data/app/serializers/spree/api/v3/line_item_serializer.rb +15 -5
  304. data/app/serializers/spree/api/v3/locale_serializer.rb +3 -1
  305. data/app/serializers/spree/api/v3/market_serializer.rb +5 -5
  306. data/app/serializers/spree/api/v3/media_serializer.rb +7 -2
  307. data/app/serializers/spree/api/v3/order_group_serializer.rb +12 -4
  308. data/app/serializers/spree/api/v3/order_serializer.rb +5 -23
  309. data/app/serializers/spree/api/v3/payment_session_serializer.rb +2 -4
  310. data/app/serializers/spree/api/v3/price_history_serializer.rb +11 -6
  311. data/app/serializers/spree/api/v3/price_serializer.rb +17 -10
  312. data/app/serializers/spree/api/v3/product_filter_price_range_serializer.rb +10 -4
  313. data/app/serializers/spree/api/v3/product_serializer.rb +3 -3
  314. data/app/serializers/spree/api/v3/refund_serializer.rb +8 -5
  315. data/app/serializers/spree/api/v3/return_line_item_serializer.rb +3 -11
  316. data/app/serializers/spree/api/v3/return_serializer.rb +3 -6
  317. data/app/serializers/spree/api/v3/seller/address_serializer.rb +12 -0
  318. data/app/serializers/spree/api/v3/seller/balance_serializer.rb +15 -10
  319. data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +7 -0
  320. data/app/serializers/spree/api/v3/seller/claim_serializer.rb +5 -0
  321. data/app/serializers/spree/api/v3/seller/country_serializer.rb +19 -0
  322. data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +1 -3
  323. data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +4 -8
  324. data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +9 -8
  325. data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +5 -0
  326. data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +5 -0
  327. data/app/serializers/spree/api/v3/seller/file_upload_serializer.rb +11 -0
  328. data/app/serializers/spree/api/v3/seller/file_upload_target_serializer.rb +10 -0
  329. data/app/serializers/spree/api/v3/seller/import_serializer.rb +2 -2
  330. data/app/serializers/spree/api/v3/seller/media_serializer.rb +2 -5
  331. data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +4 -3
  332. data/app/serializers/spree/api/v3/seller/order_serializer.rb +16 -16
  333. data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +8 -9
  334. data/app/serializers/spree/api/v3/seller/payout_serializer.rb +2 -4
  335. data/app/serializers/spree/api/v3/seller/price_history_serializer.rb +12 -0
  336. data/app/serializers/spree/api/v3/seller/price_serializer.rb +13 -0
  337. data/app/serializers/spree/api/v3/seller/product_serializer.rb +2 -0
  338. data/app/serializers/spree/api/v3/seller/profile_serializer.rb +7 -7
  339. data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +8 -0
  340. data/app/serializers/spree/api/v3/seller/return_serializer.rb +8 -5
  341. data/app/serializers/spree/api/v3/seller/state_serializer.rb +10 -0
  342. data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +3 -0
  343. data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +6 -7
  344. data/app/serializers/spree/api/v3/seller/variant_serializer.rb +8 -4
  345. data/app/serializers/spree/api/v3/stock_location_serializer.rb +8 -1
  346. data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +1 -3
  347. data/app/serializers/spree/api/v3/store_credit_serializer.rb +3 -5
  348. data/app/serializers/spree/api/v3/tax_line_serializer.rb +2 -4
  349. data/app/serializers/spree/api/v3/variant_serializer.rb +3 -3
  350. data/app/services/spree/api/v3/filter_predicates.rb +29 -0
  351. data/app/services/spree/api/v3/filter_table.rb +337 -0
  352. data/app/services/spree/api/v3/filters_aggregator.rb +2 -2
  353. data/app/services/spree/api/v3/request_schema.rb +430 -0
  354. data/app/services/spree/webhooks/deliver_webhook.rb +7 -3
  355. data/config/initializers/typelizer.rb +1 -1
  356. data/config/routes.rb +5 -3
  357. data/lib/spree/api/configuration.rb +5 -0
  358. data/lib/spree/api/dependencies.rb +7 -6
  359. data/lib/spree/api/middleware/request_size_limit.rb +24 -3
  360. data/lib/spree/api/openapi/filter_documentation.rb +136 -0
  361. data/lib/spree/api/openapi/schema_helper.rb +126 -80
  362. data/lib/spree/api/preference_families.rb +46 -0
  363. data/lib/spree/api/preference_types.rb +138 -0
  364. data/lib/spree/api/typelizer_generation.rb +4 -0
  365. data/lib/tasks/filters.rake +12 -0
  366. data/lib/typelizer/open_enums.rb +10 -0
  367. metadata +60 -10
  368. data/app/controllers/concerns/spree/api/v3/address_params.rb +0 -17
  369. data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +0 -35
  370. data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +0 -54
  371. data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +0 -21
@@ -5,6 +5,10 @@ module Spree
5
5
  class RefundReasonsController < ResourceController
6
6
  scoped_resource :settings
7
7
 
8
+ request_params :reason do |body|
9
+ body.include_attributes Spree::Api::V3::Admin::ReasonRequestSchema
10
+ end
11
+
8
12
  protected
9
13
 
10
14
  def model_class
@@ -16,7 +20,7 @@ module Spree
16
20
  end
17
21
 
18
22
  def permitted_params
19
- params.permit(*model_additional_permitted_attributes, :name, :active)
23
+ params.permit(*permitted_attributes)
20
24
  end
21
25
  end
22
26
  end
@@ -11,6 +11,14 @@ module Spree
11
11
  class SavedReportsController < ResourceController
12
12
  scoped_resource :reports
13
13
 
14
+ request_params :saved_report do |body|
15
+ body.attribute :name, :string, required: true, on: :create
16
+ body.attribute :description, :string, nullable: true
17
+ body.attribute :query, :hash,
18
+ required: true, on: :create,
19
+ description: 'A reporting query, validated against the reporting registry on save.'
20
+ end
21
+
14
22
  protected
15
23
 
16
24
  def model_class
@@ -31,7 +39,7 @@ module Spree
31
39
  # nested hashes — they would be decoded to integers on save and
32
40
  # never resolve again. Extension attributes are splatted in.
33
41
  def permitted_params
34
- params.permit(:name, :description, *model_additional_permitted_attributes, query: {})
42
+ params.permit(*permitted_attributes)
35
43
  end
36
44
 
37
45
  def build_resource
@@ -14,6 +14,40 @@ module Spree
14
14
 
15
15
  QUERY_KEYS = %w[metrics dimensions filters metric_filters time_range compare sort limit currency].freeze
16
16
 
17
+ request_params 'ReportingQueryParams', action: :query do |body|
18
+ body.attribute :metrics, :array, of: :string,
19
+ required: true,
20
+ description: 'Registered metric names, from the reporting schema endpoint.'
21
+ body.attribute :dimensions, :array, of: :any, permit: false, description: <<~TEXT.squish
22
+ Up to #{Spree::Reporting::Query::MAX_DIMENSIONS} dimensions to break the metrics down by. Each is a dimension
23
+ name, or `{ name, grain, include_empty }`: `grain` (`hour`, `day`, `week`, `month`) buckets a time
24
+ dimension, and `include_empty` lists members with no matching rows where the schema entry supports it.
25
+ TEXT
26
+ body.attribute :filters, :array, description: 'Narrows the rows by dimension value.' do |filter|
27
+ filter.attribute :dimension, :string, required: true
28
+ filter.attribute :op, :string, required: true, choices: Spree::Reporting::Query::FILTER_OPS
29
+ filter.attribute :value, :any, required: true, description: 'One value for `eq`, a list for `in`.'
30
+ end
31
+ body.attribute :metric_filters, :array,
32
+ description: "Filters on an aggregate, such as `units_sold = 0`. Narrows the rows only; the totals stay the period's real figure. The metric must also appear in `metrics`, and cannot be a derived one." do |metric_filter|
33
+ metric_filter.attribute :metric, :string, required: true
34
+ metric_filter.attribute :op, :string,
35
+ required: true,
36
+ choices: Spree::Reporting::Query::METRIC_FILTER_OPS
37
+ metric_filter.attribute :value, :number, required: true
38
+ end
39
+ body.attribute :time_range, :object,
40
+ description: "A named preset (`last_month`, `week_to_date`, any `last_<n>_<days|weeks|months>`), or ISO 8601 dates or times in `since` and `until` (a bare date covers the store's whole day). Defaults to the last 30 days, in the store's time zone." do |time_range|
41
+ time_range.attribute :preset, :string
42
+ time_range.attribute :since, :string
43
+ time_range.attribute :until, :string
44
+ end
45
+ body.attribute :compare, :string, choices: Spree::Reporting::Query::COMPARE_MODES
46
+ body.attribute :sort, :string, description: 'A metric name; prefix it with `-` to sort descending.'
47
+ body.attribute :limit, :integer, description: "At most #{Spree::Reporting::Query::MAX_LIMIT}."
48
+ body.attribute :currency, :currency
49
+ end
50
+
17
51
  # POST /api/v3/admin/reporting/query
18
52
  def query
19
53
  reporting_query = Spree::Reporting::Query.new(store: current_store, params: query_params)
@@ -9,6 +9,7 @@ module Spree
9
9
  include Spree::Api::V3::Admin::StoreContext
10
10
  include Spree::Api::V3::AdminAuthentication
11
11
  include Spree::Api::V3::ScopedAuthorization
12
+ include Spree::Api::V3::StrictMoneyParams
12
13
  # External-identity addressing for every admin resource whose model
13
14
  # opts in via Spree::HasExternalReferences — the concern's guards
14
15
  # no-op for everything else. Sitting here rather than per controller
@@ -5,6 +5,10 @@ module Spree
5
5
  class ReturnReasonsController < ResourceController
6
6
  scoped_resource :settings
7
7
 
8
+ request_params :reason do |body|
9
+ body.include_attributes Spree::Api::V3::Admin::ReasonRequestSchema
10
+ end
11
+
8
12
  protected
9
13
 
10
14
  def model_class
@@ -16,7 +20,7 @@ module Spree
16
20
  end
17
21
 
18
22
  def permitted_params
19
- params.permit(*model_additional_permitted_attributes, :name, :active)
23
+ params.permit(*permitted_attributes)
20
24
  end
21
25
  end
22
26
  end
@@ -13,6 +13,18 @@ module Spree
13
13
 
14
14
  scoped_resource :staff
15
15
 
16
+ request_params :role do |body|
17
+ body.attribute :name, :string,
18
+ required: true, on: :create,
19
+ example: 'order_manager',
20
+ description: 'Unique role name, the machine identifier shown capitalized in the dashboard.'
21
+ body.attribute :description, :string, nullable: true, example: 'Handles daily orders'
22
+ # A caller may only grant permissions they hold themselves.
23
+ body.attribute :permissions, :array, of: :string,
24
+ example: %w[write_orders read_customers],
25
+ description: 'Permission keys (`read_orders`, `write_products`, ...) from the permissions endpoint. You can only grant keys you hold yourself.'
26
+ end
27
+
16
28
  # POST /api/v3/admin/roles
17
29
  # A caller may only grant permissions they effectively hold — the
18
30
  # same anti-amplification rule as role grants and API-key minting.
@@ -58,7 +70,7 @@ module Spree
58
70
  end
59
71
 
60
72
  def permitted_params
61
- params.permit(*model_additional_permitted_attributes, :name, :description, permissions: [])
73
+ params.permit(*permitted_attributes)
62
74
  end
63
75
 
64
76
  private
@@ -12,6 +12,12 @@ module Spree
12
12
  class SellerPayoutsController < ResourceController
13
13
  scoped_resource :payouts
14
14
 
15
+ request_params 'SellerPayoutCompleteParams', action: :complete do |body|
16
+ body.attribute :reference, :string,
17
+ example: 'TRF-8842',
18
+ description: "The provider's own id for the settlement, when one made it."
19
+ end
20
+
15
21
  # PATCH /api/v3/admin/seller_payouts/:id/complete
16
22
  #
17
23
  # What the built-in provider waits for: the operator saying the bank
@@ -12,6 +12,21 @@ module Spree
12
12
  class SellerRequirementSubmissionsController < ResourceController
13
13
  scoped_resource :sellers
14
14
 
15
+ request_params 'SellerRequirementWaiveParams', action: :create do |body|
16
+ body.attribute :requirement_id, :id,
17
+ required: true,
18
+ example: 'selreq_UkLWZg9DAJ',
19
+ description: 'The requirement the seller is excused from.'
20
+ body.attribute :review_note, :string, description: 'Why the seller is excused. Kept with the decision.'
21
+ end
22
+
23
+ %i[accept reject].each do |action|
24
+ request_params('SellerRequirementReviewParams', action: action) do |body|
25
+ body.attribute :review_note, :string,
26
+ description: 'Kept with the decision. On a rejection it is the reason sent back to the seller.'
27
+ end
28
+ end
29
+
15
30
  before_action :set_resource, only: [:show, :accept, :reject, :download]
16
31
 
17
32
  # POST /api/v3/admin/sellers/:seller_id/requirement_submissions
@@ -16,6 +16,36 @@ module Spree
16
16
  subclassed_via -> { Spree.seller_requirements },
17
17
  unknown_type_error: 'unknown_seller_requirement_type'
18
18
 
19
+ # `type` is stripped before assignment by the subclassed-resource
20
+ # flow, so a saved row's kind can never change — which matters
21
+ # because its submissions answered the old one.
22
+ request_params :seller_requirement do |body|
23
+ body.attribute :type, :string,
24
+ required: true,
25
+ only: :create,
26
+ example: 'document',
27
+ description: 'The kind, from the seller requirement types endpoint.'
28
+ body.attribute :name, :string,
29
+ example: 'Business registration',
30
+ description: 'What the seller sees. Required for kinds that can be added more than once, since the wording is the only thing telling them apart. Left blank on the others, the kind names itself.'
31
+ body.attribute :description, :string,
32
+ example: 'A copy of your certificate of incorporation.',
33
+ description: 'Instructions shown to the seller.'
34
+ body.attribute :position, :integer, example: 1, description: 'Place in the checklist.'
35
+ body.attribute :active, :boolean, example: true
36
+ body.attribute :required, :boolean,
37
+ example: true,
38
+ description: 'Whether this blocks approval. Off means recommended.'
39
+ body.attribute :preferences, :hash,
40
+ example: { accepted_content_types: ['application/pdf'] },
41
+ description: "Configuration for this kind, per its type's `schema`."
42
+ body.attribute :metadata, :hash
43
+ # Permitted per kind, from the kind's own `additional_permitted_attributes`.
44
+ body.attribute :custom_field_definition_ids, :array, of: :id,
45
+ permit: false,
46
+ description: 'Custom field definitions this requirement asks the seller to fill in (`required_custom_fields` kind).'
47
+ end
48
+
19
49
  # GET /api/v3/admin/seller_requirements/types
20
50
  #
21
51
  # The kinds an operator can add, with the shape of each one's
@@ -49,7 +79,7 @@ module Spree
49
79
  # Config a kind takes beyond its preferences — a reference
50
80
  # list gets its own picker, not a text box.
51
81
  association_fields: association_fields_for(klass),
52
- preference_schema: klass.serialized_preference_schema
82
+ schema: klass.preference_json_schema
53
83
  }
54
84
  end
55
85
 
@@ -70,12 +100,8 @@ module Spree
70
100
  super.ordered
71
101
  end
72
102
 
73
- # `type` is stripped before assignment by the subclassed-resource
74
- # flow, so a saved row's kind can never change — which matters
75
- # because its submissions answered the old one.
76
103
  def permitted_params
77
- params.permit(:type, :name, :description, :position, :active, :required,
78
- preferences: {}, metadata: {})
104
+ params.permit(*declared_permitted_attributes)
79
105
  end
80
106
 
81
107
  # `types` is read-only discovery — maps to the read scope.
@@ -19,6 +19,80 @@ module Spree
19
19
  before_action :set_resource, only: [:show, :update, :destroy, :invite, :approve, :suspend, :reject,
20
20
  :onboarding, :reopen_onboarding]
21
21
 
22
+ # Enumerated rather than borrowing the legacy global list, which
23
+ # permits :id, :user_id and :deleted_at — the first of which would
24
+ # reintroduce the address-by-id hole below.
25
+ # The seller's own profile fields, plus the settlement and tax
26
+ # configuration only the operator sets. `status` is absent by
27
+ # design — see the class comment.
28
+ #
29
+ # Addresses are written as nested attributes, never as ids: an
30
+ # address has no store of its own, so accepting `billing_address_id`
31
+ # would bind an arbitrary row and the serializer would render it
32
+ # back in full — an enumeration oracle over every customer address
33
+ # on the installation.
34
+ request_params :seller do |body|
35
+ body.external_references
36
+ body.attribute :name, :string, required: true, on: :create, example: 'Northwind Books'
37
+ body.attribute :slug, :string,
38
+ example: 'northwind-books',
39
+ description: 'URL-safe slug, derived from the name when omitted.'
40
+ body.attribute :contact_email, :string, nullable: true, example: 'hi@northwind.example'
41
+ body.attribute :billing_email, :string, nullable: true, example: 'billing@northwind.example'
42
+ body.attribute :about, :string,
43
+ nullable: true,
44
+ example: '<p>Independent bookshop.</p>',
45
+ description: "Sanitized HTML: the seller's public description."
46
+ body.attribute :logo_signed_id, :string,
47
+ nullable: true,
48
+ description: 'A `signed_id` from the files upload endpoint to set the image, `null` to remove it, or omit the key to leave it untouched. The same applies to `square_logo_signed_id` and `cover_photo_signed_id`.'
49
+ body.attribute :square_logo_signed_id, :string, nullable: true
50
+ body.attribute :cover_photo_signed_id, :string, nullable: true
51
+ body.attribute :tax_remittance, :string, choices: Spree::Seller::TAX_REMITTANCES, example: 'seller'
52
+ body.attribute :payouts_schedule_interval, :string,
53
+ nullable: true,
54
+ choices: Spree::Seller::PAYOUT_INTERVALS
55
+ body.attribute :minimum_payout_amount, :decimal, nullable: true, example: '25.0'
56
+ body.attribute :holiday_mode_until, :datetime,
57
+ nullable: true,
58
+ description: 'Set while the seller is away: the catalog stays but stops selling.'
59
+ body.attribute :legal_name, :string, nullable: true
60
+ body.attribute :registration_number, :string, nullable: true
61
+ body.attribute :metadata, :hash
62
+ body.attribute :billing_address, :object,
63
+ as: 'SellerAddressParams',
64
+ description: "The seller's own billing address, written inline. There is no `billing_address_id`: an address belongs to whoever it was created for, so it is never referenced by id." do |billing_address|
65
+ billing_address.include_attributes Spree::Api::V3::AddressRequestSchema
66
+ end
67
+ body.attribute :custom_fields, :array, of: Spree::Api::V3::CustomFieldValueRequestSchema,
68
+ description: 'Custom field values, each validated against its definition.'
69
+ end
70
+
71
+ request_params 'SellerInviteParams', action: :invite do |body|
72
+ body.attribute :email, :string, required: true, example: 'seller@example.com'
73
+ body.attribute :role_id, :id,
74
+ nullable: true,
75
+ example: 'role_UkLWZg9DAJ',
76
+ description: "A role this seller owns; defaults to the seller's own admin role."
77
+ end
78
+
79
+ request_params 'SellerApproveParams', action: :approve do |body|
80
+ body.attribute :override_requirements, :boolean,
81
+ description: 'Admits a seller whose onboarding checklist is unfinished: the operator\'s deliberate exception, which the `seller.approved` event records along with what was outstanding.'
82
+ end
83
+
84
+ request_params 'SellerReopenOnboardingParams', action: :reopen_onboarding do |body|
85
+ body.attribute :note, :string, description: 'What the seller has to fix.'
86
+ end
87
+
88
+ request_params 'SellerSuspendParams', action: :suspend do |body|
89
+ body.attribute :reason, :string, example: 'Counterfeit goods'
90
+ end
91
+
92
+ request_params 'SellerRejectParams', action: :reject do |body|
93
+ body.attribute :reason, :string, example: 'Incomplete paperwork'
94
+ end
95
+
22
96
  # POST /api/v3/admin/sellers/:id/invite
23
97
  #
24
98
  # Opens the seller's team to someone. They become a member when they
@@ -125,29 +199,8 @@ module Spree
125
199
  { store: :seller_requirements, logo_attachment: :blob, cover_photo_attachment: :blob }]
126
200
  end
127
201
 
128
- # Enumerated rather than borrowing the legacy global list, which
129
- # permits :id, :user_id and :deleted_at — the first of which would
130
- # reintroduce the address-by-id hole below.
131
- # The seller's own profile fields, plus the settlement and tax
132
- # configuration only the operator sets. `status` is absent by
133
- # design — see the class comment.
134
- #
135
- # Addresses are written as nested attributes, never as ids: an
136
- # address has no store of its own, so accepting `billing_address_id`
137
- # would bind an arbitrary row and the serializer would render it
138
- # back in full — an enumeration oracle over every customer address
139
- # on the installation.
140
202
  def permitted_params
141
- normalize_params(
142
- params.permit(:name, :slug, :contact_email, :billing_email, :about,
143
- :logo, :square_logo, :cover_photo,
144
- :tax_remittance, :payouts_schedule_interval, :minimum_payout_amount,
145
- :holiday_mode_until,
146
- :legal_name, :registration_number,
147
- metadata: {},
148
- billing_address: Spree::Api::V3::AddressParams::ADDRESS_KEYS,
149
- custom_fields: [:id, :custom_field_definition_id, :value, { value: [] }, { value: {} }])
150
- )
203
+ normalize_params(params.permit(*declared_permitted_attributes))
151
204
  end
152
205
 
153
206
  # Creating a seller provisions their stock location too, so it goes
@@ -14,6 +14,35 @@ module Spree
14
14
  skip_scope_check!
15
15
  skip_before_action :authenticate_admin!, only: [:show, :countries, :create]
16
16
 
17
+ request_params 'SetupParams', action: :create do |body|
18
+ body.attribute :setup_token, :string,
19
+ required: true,
20
+ permit: false,
21
+ description: 'The one-time token from the install output.'
22
+ body.attribute :email, :string, required: true, format: :email, example: 'owner@example.com'
23
+ body.attribute :password, :string, required: true
24
+ body.attribute :password_confirmation, :string
25
+ body.attribute :first_name, :string, example: 'Olivia'
26
+ body.attribute :last_name, :string, example: 'Owner'
27
+ body.attribute :store_name, :string, permit: false, example: 'My Store'
28
+ body.attribute :country_code, :country,
29
+ required: true,
30
+ permit: false,
31
+ example: 'US',
32
+ description: 'ISO 3166-1 alpha-2 country the store sells from. It determines the default market, the warehouse, the delivery zones and the currency.'
33
+ body.attribute :locale, :locale,
34
+ permit: false,
35
+ example: 'en',
36
+ description: "Storefront locale. Defaults to the country's own language."
37
+ body.attribute :currency, :currency,
38
+ permit: false,
39
+ example: 'USD',
40
+ description: "ISO 4217 currency. Defaults to the country's own currency: pass one only when the store prices in something else."
41
+ body.attribute :sample_data, :boolean,
42
+ permit: false,
43
+ description: 'Load the demo catalog, customers and orders in the background once the admin account exists. The load takes minutes, so the response does not wait for it.'
44
+ end
45
+
17
46
  # Only create checks the setup token, so only create needs the strict
18
47
  # login budget against guessing. The status and countries reads stay
19
48
  # on the general per-caller limit: sharing the login budget with them
@@ -43,15 +72,13 @@ module Spree
43
72
  end
44
73
 
45
74
  # POST /api/v3/admin/auth/setup
46
- # Body: { setup_token, email, password, password_confirmation?,
47
- # first_name?, last_name?, store_name, country_code,
48
- # locale?, currency?, sample_data? }
49
75
  # Currency defaults to the country's own; an unknown code is refused
50
76
  # rather than ignored, since the token is spent in the same request.
51
77
  def create
52
78
  return render_setup_unavailable unless setup_token_usable?
53
79
  return render_missing_country if country.nil?
54
80
  return render_unknown_currency if unknown_currency?
81
+ return render_unknown_locale if unknown_locale?
55
82
 
56
83
  user = nil
57
84
  store = Spree::Store.default
@@ -135,26 +162,38 @@ module Spree
135
162
  )
136
163
  end
137
164
 
165
+ # Blank means "use the country's own language"; another spelling or a
166
+ # region Spree does not list moves to the listed locale, but a code
167
+ # Spree cannot place at all is refused before the token is spent.
168
+ def unknown_locale?
169
+ params[:locale].present? && Spree::Locales.listed(params[:locale]).nil?
170
+ end
171
+
172
+ def render_unknown_locale
173
+ message = "Unknown locale #{params[:locale]}"
174
+
175
+ render_error(
176
+ code: ERROR_CODES[:validation_error],
177
+ message: message,
178
+ status: :unprocessable_content,
179
+ details: { locale: [message] }
180
+ )
181
+ end
182
+
138
183
  def country_payload(country)
139
184
  {
140
185
  code: country.iso,
141
- name: country.name,
142
186
  currency: country.default_currency,
143
187
  locales: offerable_locales(country)
144
188
  }
145
189
  end
146
190
 
147
- # A country's official languages, minus any Spree has no translations
148
- # for — Switzerland speaks Romansh and Spree does not, so offering it
149
- # would point a storefront at a language with nothing behind it.
150
- # English closes the gap for countries whose languages all fall
151
- # through, and is always offered alongside.
191
+ # A country's official languages, as the locales Spree lists for them
192
+ # (Switzerland gives de, fr, it and rm) — content locales, whether
193
+ # or not Spree ships translations, since the storefront and dashboard
194
+ # carry their own. English stands in for a country with none listed.
152
195
  def offerable_locales(country)
153
- country.official_locales.filter_map { |language| Spree.locale_for_language(language, available_locales) }.presence || ['en']
154
- end
155
-
156
- def available_locales
157
- @available_locales ||= Spree.available_locales
196
+ country.official_locales.filter_map { |language| Spree::Locales.for_language(language) }.uniq.presence || ['en']
158
197
  end
159
198
 
160
199
  # Token mismatch, spent token, and already-set-up all render the
@@ -172,7 +211,7 @@ module Spree
172
211
  end
173
212
 
174
213
  def admin_user_params
175
- params.permit(:email, :password, :password_confirmation, :first_name, :last_name)
214
+ params.permit(*declared_permitted_attributes)
176
215
  end
177
216
 
178
217
  # The seed already created the default store (every downstream seed
@@ -10,6 +10,43 @@ module Spree
10
10
 
11
11
  before_action :require_stock_levels!, only: [:bulk_upsert]
12
12
 
13
+ # Stock levels are auto-created against a (variant, stock_location)
14
+ # pair and never re-pointed, so update only touches the count and
15
+ # backorder flag, not the variant or location.
16
+ request_params :stock_level do |body|
17
+ body.external_references
18
+ body.attribute :count_on_hand, :integer,
19
+ description: 'The count the shelf should end at: a whole number of zero or more. The API records the difference as an `adjusted` movement, so the correction appears in the stock history.'
20
+ body.attribute :adjustment, :integer,
21
+ description: 'A signed change to the shelf instead of a target count, applied to the count the API holds at that moment and recorded the same way. Cannot be sent together with `count_on_hand`.'
22
+ body.attribute :backorderable, :boolean,
23
+ description: 'Whether this location sells the variant beyond what it holds.'
24
+ # Optional so an audit requirement never turns an existing
25
+ # endpoint into a 422.
26
+ body.attribute :reason, :string,
27
+ description: 'Labels the correction in the stock history. Defaults to "Manual adjustment".'
28
+ body.attribute :metadata, :hash
29
+ end
30
+
31
+ request_params 'StockLevelBulkUpsertParams', action: :bulk_upsert do |body|
32
+ body.attribute :stock_levels, :array,
33
+ required: true,
34
+ as: 'StockLevelBulkUpsertRowParams',
35
+ description: 'Send an empty list to change nothing.' do |stock_level|
36
+ stock_level.attribute :variant_id, :id, required: true, example: 'variant_xY9'
37
+ stock_level.attribute :stock_location_id, :id, required: true, example: 'sloc_aBc'
38
+ stock_level.attribute :count_on_hand, :integer,
39
+ nullable: true,
40
+ example: 42,
41
+ description: 'The absolute level the external system reports.'
42
+ stock_level.attribute :adjustment, :integer,
43
+ nullable: true,
44
+ example: -3,
45
+ description: 'A relative change, for feeds that report movements rather than levels. Each row needs `count_on_hand` or `adjustment`.'
46
+ stock_level.attribute :backorderable, :boolean, nullable: true
47
+ end
48
+ end
49
+
13
50
  def bulk_upsert
14
51
  authorize! :update, Spree::StockLevel
15
52
 
@@ -101,16 +138,8 @@ module Spree
101
138
  collection.order(Spree::StockLevel.arel_table[:id].asc)
102
139
  end
103
140
 
104
- # Stock levels are auto-created against a (variant, stock_location)
105
- # pair and never re-pointed, so update only touches the count and
106
- # backorder flag — not the variant or location FKs.
107
- #
108
- # `reason` labels the correction in the stock history. It stays
109
- # optional so an audit requirement never turns an existing endpoint
110
- # into a 422; omitting it falls back to a translated default.
111
141
  def permitted_params
112
- params.permit(*model_additional_permitted_attributes, :count_on_hand, :adjustment, :backorderable, :reason,
113
- metadata: {})
142
+ params.permit(*permitted_attributes)
114
143
  end
115
144
 
116
145
  private
@@ -5,6 +5,46 @@ module Spree
5
5
  class StockLocationsController < ResourceController
6
6
  scoped_resource :stock
7
7
 
8
+ request_params :stock_location do |body|
9
+ body.external_references
10
+ body.attribute :name, :string, required: true, on: :create, example: 'Brooklyn warehouse'
11
+ body.attribute :admin_name, :string, nullable: true, description: 'Internal name shown only in the admin.'
12
+ body.attribute :active, :boolean
13
+ body.attribute :default, :boolean, description: 'Setting to true demotes the previous default.'
14
+ body.attribute :kind, :string,
15
+ choices: Spree::StockLocation::KINDS,
16
+ open: true,
17
+ example: 'warehouse',
18
+ description: 'Categorizes the location.'
19
+ body.attribute :propagate_all_variants, :boolean
20
+ body.attribute :backorderable_default, :boolean
21
+ body.attribute :address1, :string, nullable: true
22
+ body.attribute :address2, :string, nullable: true
23
+ body.attribute :city, :string, nullable: true
24
+ body.attribute :zipcode, :string, nullable: true
25
+ body.attribute :phone, :string, nullable: true
26
+ body.attribute :company, :string, nullable: true
27
+ body.attribute :country_code, :country,
28
+ nullable: true,
29
+ example: 'US',
30
+ description: 'ISO-3166 alpha-2 country code.'
31
+ body.attribute :state_code, :string,
32
+ nullable: true,
33
+ example: 'NY',
34
+ description: "State or province abbreviation, resolved against the selected country's states."
35
+ body.attribute :state_name, :string,
36
+ nullable: true,
37
+ description: "Free-text state for countries that don't have a states list."
38
+ body.attribute :pickup_enabled, :boolean
39
+ body.attribute :pickup_stock_policy, :string,
40
+ choices: Spree::StockLocation::PICKUP_STOCK_POLICIES,
41
+ description: '`local` collects only items at this location; `any` lets items transfer in from other locations (ship-to-store).'
42
+ body.attribute :pickup_ready_in_minutes, :integer, nullable: true
43
+ body.attribute :returns_enabled, :boolean,
44
+ description: 'Whether customers may send returns to this location.'
45
+ body.attribute :pickup_instructions, :string, nullable: true
46
+ end
47
+
8
48
  protected
9
49
 
10
50
  def model_class
@@ -26,15 +66,7 @@ module Spree
26
66
  end
27
67
 
28
68
  def permitted_params
29
- params.permit(
30
- *model_additional_permitted_attributes,
31
- :name, :admin_name, :active, :default,
32
- :kind, :propagate_all_variants, :backorderable_default,
33
- :address1, :address2, :city, :zipcode, :phone, :company,
34
- :country_code, :state_code, :state_name,
35
- :pickup_enabled, :pickup_stock_policy, :returns_enabled,
36
- :pickup_ready_in_minutes, :pickup_instructions
37
- )
69
+ params.permit(*permitted_attributes)
38
70
  end
39
71
  end
40
72
  end