spree_api 5.6.1 → 6.0.0.beta2

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 (542) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +28 -0
  3. data/Rakefile +1 -1
  4. data/app/controllers/concerns/spree/api/v3/address_params.rb +17 -0
  5. data/app/controllers/concerns/spree/api/v3/admin/product_listing.rb +46 -0
  6. data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +110 -0
  7. data/app/controllers/concerns/spree/api/v3/admin/receivable_actions.rb +68 -0
  8. data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +27 -0
  9. data/app/controllers/concerns/spree/api/v3/admin/role_grant_guard.rb +69 -33
  10. data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +86 -0
  11. data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +97 -0
  12. data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +12 -6
  13. data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +91 -0
  14. data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +20 -5
  15. data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +41 -5
  16. data/app/controllers/concerns/spree/api/v3/authentication_strategies.rb +48 -0
  17. data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +4 -6
  18. data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +52 -16
  19. data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +37 -0
  20. data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +41 -0
  21. data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +35 -0
  22. data/app/controllers/concerns/spree/api/v3/error_handler.rb +53 -11
  23. data/app/controllers/concerns/spree/api/v3/idempotent.rb +10 -4
  24. data/app/controllers/concerns/spree/api/v3/items_payload.rb +54 -0
  25. data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +23 -3
  26. data/app/controllers/concerns/spree/api/v3/key_store_context.rb +31 -0
  27. data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +3 -3
  28. data/app/controllers/concerns/spree/api/v3/order_lock.rb +22 -3
  29. data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +112 -0
  30. data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +105 -0
  31. data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +117 -0
  32. data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +157 -0
  33. data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +76 -0
  34. data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +116 -0
  35. data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +128 -0
  36. data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +7 -4
  37. data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +42 -0
  38. data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +40 -6
  39. data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +80 -26
  40. data/app/controllers/concerns/spree/api/v3/seller/auth_cookies.rb +62 -0
  41. data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +127 -0
  42. data/app/controllers/concerns/spree/api/v3/seller_authentication.rb +40 -0
  43. data/app/controllers/concerns/spree/api/v3/storefront_access.rb +38 -0
  44. data/app/controllers/concerns/spree/api/v3/streams_shipping_label.rb +37 -0
  45. data/app/controllers/concerns/spree/api/v3/tax_identifier_validation.rb +41 -0
  46. data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +11 -14
  47. data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +1 -1
  48. data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +18 -9
  49. data/app/controllers/spree/api/v3/admin/auth_controller.rb +138 -22
  50. data/app/controllers/spree/api/v3/admin/base_controller.rb +2 -0
  51. data/app/controllers/spree/api/v3/admin/catalog_assignments_controller.rb +27 -0
  52. data/app/controllers/spree/api/v3/admin/catalogs/base_controller.rb +29 -0
  53. data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +40 -0
  54. data/app/controllers/spree/api/v3/admin/catalogs/products_controller.rb +107 -0
  55. data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +75 -0
  56. data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +191 -0
  57. data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +28 -41
  58. data/app/controllers/spree/api/v3/admin/categories_controller.rb +16 -7
  59. data/app/controllers/spree/api/v3/admin/channels_controller.rb +50 -2
  60. data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +25 -0
  61. data/app/controllers/spree/api/v3/admin/claims_controller.rb +31 -0
  62. data/app/controllers/spree/api/v3/admin/collection_rules_controller.rb +40 -0
  63. data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +101 -0
  64. data/app/controllers/spree/api/v3/admin/collections_controller.rb +56 -0
  65. data/app/controllers/spree/api/v3/admin/commission_lines_controller.rb +39 -0
  66. data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +174 -0
  67. data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +65 -0
  68. data/app/controllers/spree/api/v3/admin/companies/base_controller.rb +29 -0
  69. data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +56 -0
  70. data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +66 -0
  71. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +137 -0
  72. data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +46 -0
  73. data/app/controllers/spree/api/v3/admin/companies_controller.rb +59 -0
  74. data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +166 -0
  75. data/app/controllers/spree/api/v3/admin/consent_records_controller.rb +31 -0
  76. data/app/controllers/spree/api/v3/admin/countries_controller.rb +12 -4
  77. data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +19 -4
  78. data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +5 -5
  79. data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +1 -1
  80. data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +4 -4
  81. data/app/controllers/spree/api/v3/admin/customers/base_controller.rb +1 -1
  82. data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +2 -3
  83. data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +43 -0
  84. data/app/controllers/spree/api/v3/admin/customers_controller.rb +190 -11
  85. data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +24 -20
  86. data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +60 -0
  87. data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +54 -0
  88. data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +114 -0
  89. data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +243 -0
  90. data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +80 -0
  91. data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +107 -0
  92. data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +116 -0
  93. data/app/controllers/spree/api/v3/admin/digital_links_controller.rb +48 -0
  94. data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +17 -3
  95. data/app/controllers/spree/api/v3/admin/exchanges_controller.rb +31 -0
  96. data/app/controllers/spree/api/v3/admin/exports_controller.rb +2 -2
  97. data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +1 -1
  98. data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +3 -2
  99. data/app/controllers/spree/api/v3/admin/imports_controller.rb +71 -8
  100. data/app/controllers/spree/api/v3/admin/integrations_controller.rb +67 -0
  101. data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +5 -5
  102. data/app/controllers/spree/api/v3/admin/invitations_controller.rb +5 -1
  103. data/app/controllers/spree/api/v3/admin/locales_controller.rb +3 -1
  104. data/app/controllers/spree/api/v3/admin/markets_controller.rb +9 -5
  105. data/app/controllers/spree/api/v3/admin/me_controller.rb +4 -30
  106. data/app/controllers/spree/api/v3/admin/media_controller.rb +88 -38
  107. data/app/controllers/spree/api/v3/admin/media_library_controller.rb +156 -0
  108. data/app/controllers/spree/api/v3/admin/option_types_controller.rb +1 -0
  109. data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +25 -0
  110. data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +43 -0
  111. data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +1 -1
  112. data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +56 -0
  113. data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +66 -0
  114. data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +86 -0
  115. data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +99 -0
  116. data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +62 -0
  117. data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +83 -0
  118. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +45 -67
  119. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +40 -22
  120. data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +75 -0
  121. data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +36 -18
  122. data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +39 -18
  123. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +70 -0
  124. data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +2 -2
  125. data/app/controllers/spree/api/v3/admin/orders/tax_identifiers_controller.rb +41 -0
  126. data/app/controllers/spree/api/v3/admin/orders/tax_lines_controller.rb +32 -0
  127. data/app/controllers/spree/api/v3/admin/orders_controller.rb +164 -33
  128. data/app/controllers/spree/api/v3/admin/package_types_controller.rb +39 -0
  129. data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +1 -1
  130. data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +15 -4
  131. data/app/controllers/spree/api/v3/admin/payout_providers_controller.rb +27 -0
  132. data/app/controllers/spree/api/v3/admin/permissions_controller.rb +30 -0
  133. data/app/controllers/spree/api/v3/admin/policies_controller.rb +42 -0
  134. data/app/controllers/spree/api/v3/admin/price_lists/products_controller.rb +93 -0
  135. data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +43 -29
  136. data/app/controllers/spree/api/v3/admin/prices_controller.rb +41 -4
  137. data/app/controllers/spree/api/v3/admin/product_types_controller.rb +93 -0
  138. data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +148 -0
  139. data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +24 -3
  140. data/app/controllers/spree/api/v3/admin/products_controller.rb +149 -33
  141. data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +6 -2
  142. data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +1 -1
  143. data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -5
  144. data/app/controllers/spree/api/v3/admin/purchase_orders/stock_receipts_controller.rb +32 -0
  145. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +161 -0
  146. data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +25 -0
  147. data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +45 -0
  148. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +95 -0
  149. data/app/controllers/spree/api/v3/admin/resource_controller.rb +27 -10
  150. data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +25 -0
  151. data/app/controllers/spree/api/v3/admin/returns_controller.rb +31 -0
  152. data/app/controllers/spree/api/v3/admin/roles_controller.rb +50 -6
  153. data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +83 -0
  154. data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +139 -0
  155. data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +115 -0
  156. data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +36 -0
  157. data/app/controllers/spree/api/v3/admin/sellers/balances_controller.rb +44 -0
  158. data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +77 -0
  159. data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +107 -0
  160. data/app/controllers/spree/api/v3/admin/sellers/team_controller.rb +64 -0
  161. data/app/controllers/spree/api/v3/admin/sellers_controller.rb +197 -0
  162. data/app/controllers/spree/api/v3/admin/setup_controller.rb +239 -0
  163. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +172 -0
  164. data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +3 -2
  165. data/app/controllers/spree/api/v3/admin/stock_movements_controller.rb +37 -0
  166. data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +1 -1
  167. data/app/controllers/spree/api/v3/admin/stock_transfers/stock_receipts_controller.rb +31 -0
  168. data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +134 -38
  169. data/app/controllers/spree/api/v3/admin/store_controller.rb +66 -0
  170. data/app/controllers/spree/api/v3/admin/store_credits/events_controller.rb +47 -0
  171. data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +87 -0
  172. data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +30 -0
  173. data/app/controllers/spree/api/v3/admin/tags_controller.rb +2 -2
  174. data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +4 -0
  175. data/app/controllers/spree/api/v3/admin/tax_providers_controller.rb +25 -0
  176. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +33 -0
  177. data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +33 -0
  178. data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +37 -9
  179. data/app/controllers/spree/api/v3/admin/translations_controller.rb +10 -5
  180. data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +150 -0
  181. data/app/controllers/spree/api/v3/admin/variants_controller.rb +11 -4
  182. data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +1 -1
  183. data/app/controllers/spree/api/v3/base_controller.rb +74 -16
  184. data/app/controllers/spree/api/v3/resource_controller.rb +170 -39
  185. data/app/controllers/spree/api/v3/seller/auth_controller.rb +169 -0
  186. data/app/controllers/spree/api/v3/seller/balances_controller.rb +35 -0
  187. data/app/controllers/spree/api/v3/seller/base_controller.rb +25 -0
  188. data/app/controllers/spree/api/v3/seller/claim_reasons_controller.rb +20 -0
  189. data/app/controllers/spree/api/v3/seller/countries_controller.rb +38 -0
  190. data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +265 -0
  191. data/app/controllers/spree/api/v3/seller/delivery_profiles_controller.rb +65 -0
  192. data/app/controllers/spree/api/v3/seller/delivery_zones_controller.rb +41 -0
  193. data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +21 -0
  194. data/app/controllers/spree/api/v3/seller/exports_controller.rb +195 -0
  195. data/app/controllers/spree/api/v3/seller/import_rows_controller.rb +49 -0
  196. data/app/controllers/spree/api/v3/seller/imports_controller.rb +317 -0
  197. data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +152 -0
  198. data/app/controllers/spree/api/v3/seller/invitations_controller.rb +71 -0
  199. data/app/controllers/spree/api/v3/seller/me_controller.rb +72 -0
  200. data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +111 -0
  201. data/app/controllers/spree/api/v3/seller/order_cancellation_reasons_controller.rb +25 -0
  202. data/app/controllers/spree/api/v3/seller/orders/base_controller.rb +44 -0
  203. data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +45 -0
  204. data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +38 -0
  205. data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +50 -0
  206. data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +79 -0
  207. data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +55 -0
  208. data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +82 -0
  209. data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +44 -0
  210. data/app/controllers/spree/api/v3/seller/orders_controller.rb +199 -0
  211. data/app/controllers/spree/api/v3/seller/package_types_controller.rb +100 -0
  212. data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +155 -0
  213. data/app/controllers/spree/api/v3/seller/payouts_controller.rb +47 -0
  214. data/app/controllers/spree/api/v3/seller/policies_controller.rb +57 -0
  215. data/app/controllers/spree/api/v3/seller/product_types_controller.rb +35 -0
  216. data/app/controllers/spree/api/v3/seller/products_controller.rb +394 -0
  217. data/app/controllers/spree/api/v3/seller/profile_controller.rb +137 -0
  218. data/app/controllers/spree/api/v3/seller/reasons_controller.rb +45 -0
  219. data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +95 -0
  220. data/app/controllers/spree/api/v3/seller/resource_controller.rb +75 -0
  221. data/app/controllers/spree/api/v3/seller/return_reasons_controller.rb +20 -0
  222. data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +56 -0
  223. data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +48 -0
  224. data/app/controllers/spree/api/v3/seller/team_controller.rb +103 -0
  225. data/app/controllers/spree/api/v3/seller/tracking_carriers_controller.rb +35 -0
  226. data/app/controllers/spree/api/v3/seller/transfers_controller.rb +43 -0
  227. data/app/controllers/spree/api/v3/store/account/companies_controller.rb +42 -0
  228. data/app/controllers/spree/api/v3/store/auth_controller.rb +21 -34
  229. data/app/controllers/spree/api/v3/store/base_controller.rb +4 -0
  230. data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +24 -2
  231. data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +41 -15
  232. data/app/controllers/spree/api/v3/store/carts/items_controller.rb +53 -20
  233. data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +36 -20
  234. data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +111 -0
  235. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +2 -2
  236. data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +96 -0
  237. data/app/controllers/spree/api/v3/store/carts_controller.rb +57 -12
  238. data/app/controllers/spree/api/v3/store/categories_controller.rb +6 -3
  239. data/app/controllers/spree/api/v3/store/collections/products_controller.rb +59 -0
  240. data/app/controllers/spree/api/v3/store/collections_controller.rb +36 -0
  241. data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +81 -0
  242. data/app/controllers/spree/api/v3/store/companies/base_controller.rb +24 -0
  243. data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +50 -0
  244. data/app/controllers/spree/api/v3/store/companies/members_controller.rb +66 -0
  245. data/app/controllers/spree/api/v3/store/companies/orders_controller.rb +28 -0
  246. data/app/controllers/spree/api/v3/store/companies_controller.rb +47 -0
  247. data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +90 -0
  248. data/app/controllers/spree/api/v3/store/countries_controller.rb +8 -6
  249. data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +3 -1
  250. data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +78 -0
  251. data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +52 -0
  252. data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +6 -0
  253. data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +7 -3
  254. data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +3 -3
  255. data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -3
  256. data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +91 -0
  257. data/app/controllers/spree/api/v3/store/customers_controller.rb +26 -31
  258. data/app/controllers/spree/api/v3/store/data_feeds_controller.rb +11 -0
  259. data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +58 -0
  260. data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +108 -0
  261. data/app/controllers/spree/api/v3/store/digital_links_controller.rb +105 -0
  262. data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +5 -9
  263. data/app/controllers/spree/api/v3/store/markets_controller.rb +4 -4
  264. data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +8 -9
  265. data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +94 -0
  266. data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +116 -0
  267. data/app/controllers/spree/api/v3/store/orders/tax_identifiers_controller.rb +46 -0
  268. data/app/controllers/spree/api/v3/store/orders_controller.rb +12 -15
  269. data/app/controllers/spree/api/v3/store/products/filters_controller.rb +10 -3
  270. data/app/controllers/spree/api/v3/store/products_controller.rb +25 -6
  271. data/app/controllers/spree/api/v3/store/resource_controller.rb +2 -0
  272. data/app/controllers/spree/api/v3/store/sellers_controller.rb +43 -0
  273. data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +9 -6
  274. data/app/controllers/spree/api/v3/store/wishlists_controller.rb +3 -3
  275. data/app/controllers/spree/api/v3/webhooks/fulfillments_controller.rb +88 -0
  276. data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +5 -2
  277. data/app/controllers/spree/api/v3/webhooks/payouts_controller.rb +61 -0
  278. data/app/models/spree/api/data_request_urls.rb +25 -0
  279. data/app/models/spree/api/digital_link_urls.rb +26 -0
  280. data/app/serializers/spree/api/v3/address_serializer.rb +17 -5
  281. data/app/serializers/spree/api/v3/admin/actor_serializer.rb +28 -0
  282. data/app/serializers/spree/api/v3/admin/address_serializer.rb +27 -4
  283. data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +13 -10
  284. data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +15 -2
  285. data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +15 -0
  286. data/app/serializers/spree/api/v3/admin/cart_serializer.rb +34 -0
  287. data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +32 -0
  288. data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +23 -0
  289. data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +48 -0
  290. data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +23 -0
  291. data/app/serializers/spree/api/v3/admin/catalog_product_serializer.rb +57 -0
  292. data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +38 -0
  293. data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +37 -0
  294. data/app/serializers/spree/api/v3/admin/catalog_serializer.rb +46 -0
  295. data/app/serializers/spree/api/v3/admin/category_serializer.rb +3 -2
  296. data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -1
  297. data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +16 -0
  298. data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +21 -0
  299. data/app/serializers/spree/api/v3/admin/claim_serializer.rb +28 -0
  300. data/app/serializers/spree/api/v3/admin/collection_rule_serializer.rb +22 -0
  301. data/app/serializers/spree/api/v3/admin/collection_serializer.rb +29 -0
  302. data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +67 -0
  303. data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +69 -0
  304. data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +61 -0
  305. data/app/serializers/spree/api/v3/admin/company_invitation_serializer.rb +15 -0
  306. data/app/serializers/spree/api/v3/admin/company_membership_serializer.rb +11 -0
  307. data/app/serializers/spree/api/v3/admin/company_serializer.rb +37 -0
  308. data/app/serializers/spree/api/v3/admin/concerns/external_references_attribute.rb +33 -0
  309. data/app/serializers/spree/api/v3/admin/consent_record_serializer.rb +28 -0
  310. data/app/serializers/spree/api/v3/admin/country_serializer.rb +2 -2
  311. data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -1
  312. data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +2 -2
  313. data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +2 -2
  314. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +23 -22
  315. data/app/serializers/spree/api/v3/admin/dashboard_counter_serializer.rb +24 -0
  316. data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +36 -0
  317. data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +32 -0
  318. data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +66 -1
  319. data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +15 -0
  320. data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +34 -0
  321. data/app/serializers/spree/api/v3/admin/delivery_profile_serializer.rb +65 -0
  322. data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +10 -1
  323. data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +20 -0
  324. data/app/serializers/spree/api/v3/admin/delivery_zone_member_serializer.rb +11 -0
  325. data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +29 -0
  326. data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +59 -0
  327. data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -4
  328. data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +16 -0
  329. data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +34 -0
  330. data/app/serializers/spree/api/v3/admin/export_serializer.rb +20 -1
  331. data/app/serializers/spree/api/v3/admin/fee_serializer.rb +14 -0
  332. data/app/serializers/spree/api/v3/admin/freight_summary_line_serializer.rb +46 -0
  333. data/app/serializers/spree/api/v3/admin/freight_summary_serializer.rb +16 -0
  334. data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +39 -0
  335. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +31 -9
  336. data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -3
  337. data/app/serializers/spree/api/v3/admin/import_serializer.rb +15 -2
  338. data/app/serializers/spree/api/v3/admin/integration_serializer.rb +32 -0
  339. data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +4 -4
  340. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +46 -5
  341. data/app/serializers/spree/api/v3/admin/market_serializer.rb +5 -1
  342. data/app/serializers/spree/api/v3/admin/media_serializer.rb +50 -2
  343. data/app/serializers/spree/api/v3/admin/membership_product_serializer.rb +29 -0
  344. data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +29 -0
  345. data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +50 -0
  346. data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
  347. data/app/serializers/spree/api/v3/admin/order_serializer.rb +126 -31
  348. data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +53 -0
  349. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +8 -2
  350. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -0
  351. data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +41 -0
  352. data/app/serializers/spree/api/v3/admin/permission_serializer.rb +39 -0
  353. data/app/serializers/spree/api/v3/admin/policy_serializer.rb +11 -0
  354. data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +22 -0
  355. data/app/serializers/spree/api/v3/admin/price_list_product_serializer.rb +32 -0
  356. data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +20 -8
  357. data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -12
  358. data/app/serializers/spree/api/v3/admin/price_serializer.rb +3 -0
  359. data/app/serializers/spree/api/v3/admin/product_serializer.rb +54 -8
  360. data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +39 -0
  361. data/app/serializers/spree/api/v3/admin/product_type_custom_field_definition_serializer.rb +44 -0
  362. data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +34 -0
  363. data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +6 -12
  364. data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +17 -15
  365. data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +80 -0
  366. data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +94 -0
  367. data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +27 -0
  368. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +6 -5
  369. data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +72 -0
  370. data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +16 -0
  371. data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +21 -0
  372. data/app/serializers/spree/api/v3/admin/return_serializer.rb +58 -0
  373. data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
  374. data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +32 -0
  375. data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +37 -0
  376. data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +46 -0
  377. data/app/serializers/spree/api/v3/admin/seller_requirement_serializer.rb +68 -0
  378. data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +48 -0
  379. data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +57 -0
  380. data/app/serializers/spree/api/v3/admin/seller_serializer.rb +92 -0
  381. data/app/serializers/spree/api/v3/admin/seller_team_member_serializer.rb +29 -0
  382. data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +53 -0
  383. data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +82 -0
  384. data/app/serializers/spree/api/v3/admin/state_serializer.rb +1 -1
  385. data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +65 -0
  386. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +20 -4
  387. data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +116 -0
  388. data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +57 -0
  389. data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +48 -0
  390. data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +5 -5
  391. data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +57 -0
  392. data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +36 -16
  393. data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +32 -0
  394. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +42 -7
  395. data/app/serializers/spree/api/v3/admin/store_serializer.rb +65 -1
  396. data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +39 -0
  397. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +67 -0
  398. data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +43 -0
  399. data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +21 -0
  400. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +49 -0
  401. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +49 -8
  402. data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +23 -0
  403. data/app/serializers/spree/api/v3/base_serializer.rb +61 -2
  404. data/app/serializers/spree/api/v3/cart_serializer.rb +90 -12
  405. data/app/serializers/spree/api/v3/category_serializer.rb +3 -3
  406. data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +50 -0
  407. data/app/serializers/spree/api/v3/claim_reason_serializer.rb +20 -0
  408. data/app/serializers/spree/api/v3/claim_serializer.rb +62 -0
  409. data/app/serializers/spree/api/v3/collection_serializer.rb +41 -0
  410. data/app/serializers/spree/api/v3/company_invitation_serializer.rb +28 -0
  411. data/app/serializers/spree/api/v3/company_membership_serializer.rb +28 -0
  412. data/app/serializers/spree/api/v3/company_serializer.rb +33 -0
  413. data/app/serializers/spree/api/v3/custom_field_serializer.rb +2 -2
  414. data/app/serializers/spree/api/v3/customer_serializer.rb +9 -1
  415. data/app/serializers/spree/api/v3/data_request_event_serializer.rb +30 -0
  416. data/app/serializers/spree/api/v3/data_request_serializer.rb +40 -0
  417. data/app/serializers/spree/api/v3/delivery_method_serializer.rb +12 -2
  418. data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +34 -17
  419. data/app/serializers/spree/api/v3/delivery_serializer.rb +29 -0
  420. data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +29 -0
  421. data/app/serializers/spree/api/v3/delivery_zone_serializer.rb +13 -0
  422. data/app/serializers/spree/api/v3/digital_asset_serializer.rb +23 -0
  423. data/app/serializers/spree/api/v3/digital_link_serializer.rb +6 -2
  424. data/app/serializers/spree/api/v3/discount_serializer.rb +21 -7
  425. data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +53 -0
  426. data/app/serializers/spree/api/v3/exchange_serializer.rb +61 -0
  427. data/app/serializers/spree/api/v3/fee_serializer.rb +27 -0
  428. data/app/serializers/spree/api/v3/freight_summary_serializer.rb +38 -0
  429. data/app/serializers/spree/api/v3/fulfillment_serializer.rb +28 -15
  430. data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
  431. data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
  432. data/app/serializers/spree/api/v3/import_serializer.rb +18 -4
  433. data/app/serializers/spree/api/v3/invitation_serializer.rb +1 -1
  434. data/app/serializers/spree/api/v3/line_item_serializer.rb +18 -1
  435. data/app/serializers/spree/api/v3/market_serializer.rb +2 -2
  436. data/app/serializers/spree/api/v3/{asset_serializer.rb → media_event_serializer.rb} +4 -4
  437. data/app/serializers/spree/api/v3/media_serializer.rb +48 -7
  438. data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +1 -1
  439. data/app/serializers/spree/api/v3/option_type_serializer.rb +1 -1
  440. data/app/serializers/spree/api/v3/order_group_serializer.rb +60 -0
  441. data/app/serializers/spree/api/v3/order_serializer.rb +58 -6
  442. data/app/serializers/spree/api/v3/payment_method_serializer.rb +1 -1
  443. data/app/serializers/spree/api/v3/payment_serializer.rb +2 -6
  444. data/app/serializers/spree/api/v3/payment_session_serializer.rb +10 -3
  445. data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +1 -1
  446. data/app/serializers/spree/api/v3/policy_serializer.rb +7 -2
  447. data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +1 -1
  448. data/app/serializers/spree/api/v3/product_serializer.rb +42 -10
  449. data/app/serializers/spree/api/v3/product_type_serializer.rb +17 -0
  450. data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +11 -0
  451. data/app/serializers/spree/api/v3/refund_serializer.rb +9 -3
  452. data/app/serializers/spree/api/v3/return_line_item_serializer.rb +42 -0
  453. data/app/serializers/spree/api/v3/return_reason_serializer.rb +20 -0
  454. data/app/serializers/spree/api/v3/return_serializer.rb +62 -0
  455. data/app/serializers/spree/api/v3/seller/balance_serializer.rb +35 -0
  456. data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +21 -0
  457. data/app/serializers/spree/api/v3/seller/claim_serializer.rb +25 -0
  458. data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +32 -0
  459. data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +59 -0
  460. data/app/serializers/spree/api/v3/seller/delivery_profile_serializer.rb +26 -0
  461. data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +35 -0
  462. data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +17 -0
  463. data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +26 -0
  464. data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +29 -0
  465. data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +30 -0
  466. data/app/serializers/spree/api/v3/seller/export_serializer.rb +44 -0
  467. data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +43 -0
  468. data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +76 -0
  469. data/app/serializers/spree/api/v3/seller/import_mapping_serializer.rb +20 -0
  470. data/app/serializers/spree/api/v3/seller/import_row_serializer.rb +17 -0
  471. data/app/serializers/spree/api/v3/seller/import_serializer.rb +77 -0
  472. data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +29 -0
  473. data/app/serializers/spree/api/v3/seller/media_serializer.rb +26 -0
  474. data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +44 -0
  475. data/app/serializers/spree/api/v3/seller/order_serializer.rb +119 -0
  476. data/app/serializers/spree/api/v3/seller/package_type_serializer.rb +52 -0
  477. data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +34 -0
  478. data/app/serializers/spree/api/v3/seller/payout_serializer.rb +36 -0
  479. data/app/serializers/spree/api/v3/seller/policy_serializer.rb +11 -0
  480. data/app/serializers/spree/api/v3/seller/product_serializer.rb +60 -0
  481. data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +30 -0
  482. data/app/serializers/spree/api/v3/seller/product_type_serializer.rb +29 -0
  483. data/app/serializers/spree/api/v3/seller/profile_serializer.rb +77 -0
  484. data/app/serializers/spree/api/v3/seller/reason_serializer.rb +24 -0
  485. data/app/serializers/spree/api/v3/seller/requirement_custom_field_serializer.rb +36 -0
  486. data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +62 -0
  487. data/app/serializers/spree/api/v3/seller/requirement_submission_serializer.rb +33 -0
  488. data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +24 -0
  489. data/app/serializers/spree/api/v3/seller/return_serializer.rb +51 -0
  490. data/app/serializers/spree/api/v3/seller/shipping_label_serializer.rb +23 -0
  491. data/app/serializers/spree/api/v3/seller/stock_level_serializer.rb +27 -0
  492. data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +17 -0
  493. data/app/serializers/spree/api/v3/seller/tax_identifier_serializer.rb +15 -0
  494. data/app/serializers/spree/api/v3/seller/team_member_serializer.rb +22 -0
  495. data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +49 -0
  496. data/app/serializers/spree/api/v3/seller/variant_serializer.rb +71 -0
  497. data/app/serializers/spree/api/v3/seller_serializer.rb +50 -0
  498. data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +11 -0
  499. data/app/serializers/spree/api/v3/{stock_item_serializer.rb → stock_level_serializer.rb} +5 -5
  500. data/app/serializers/spree/api/v3/stock_location_serializer.rb +11 -7
  501. data/app/serializers/spree/api/v3/stock_movement_serializer.rb +8 -15
  502. data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +11 -0
  503. data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +6 -6
  504. data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +29 -0
  505. data/app/serializers/spree/api/v3/supplier_event_serializer.rb +11 -0
  506. data/app/serializers/spree/api/v3/tax_identifier_serializer.rb +15 -0
  507. data/app/serializers/spree/api/v3/tax_line_serializer.rb +37 -0
  508. data/app/serializers/spree/api/v3/variant_serializer.rb +52 -2
  509. data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +6 -6
  510. data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
  511. data/app/services/spree/api/v3/filters_aggregator.rb +14 -12
  512. data/app/services/spree/webhooks/deliver_webhook.rb +62 -26
  513. data/app/subscribers/spree/webhook_event_subscriber.rb +9 -5
  514. data/config/brakeman.ignore +1 -1
  515. data/config/initializers/typelizer.rb +51 -4
  516. data/config/locales/en.yml +5 -0
  517. data/config/routes.rb +730 -22
  518. data/lib/spree/api/configuration.rb +19 -19
  519. data/lib/spree/api/dependencies.rb +174 -227
  520. data/lib/spree/api/engine.rb +6 -0
  521. data/lib/spree/api/openapi/schema_helper.rb +179 -13
  522. data/lib/spree/api/testing_support/v3/base.rb +45 -15
  523. data/lib/spree/api.rb +10 -4
  524. data/lib/typelizer/open_enums.rb +35 -0
  525. metadata +342 -27
  526. data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +0 -25
  527. data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +0 -42
  528. data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +0 -21
  529. data/app/controllers/spree/api/v3/store/digitals_controller.rb +0 -38
  530. data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +0 -24
  531. data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +0 -143
  532. data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +0 -15
  533. data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +0 -19
  534. data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +0 -34
  535. data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +0 -19
  536. data/app/serializers/spree/api/v3/customer_return_serializer.rb +0 -17
  537. data/app/serializers/spree/api/v3/digital_serializer.rb +0 -17
  538. data/app/serializers/spree/api/v3/reimbursement_serializer.rb +0 -27
  539. data/app/serializers/spree/api/v3/report_serializer.rb +0 -34
  540. data/app/serializers/spree/api/v3/return_authorization_serializer.rb +0 -31
  541. data/app/serializers/spree/api/v3/return_item_serializer.rb +0 -53
  542. data/app/serializers/spree/api/v3/shipping_category_serializer.rb +0 -11
@@ -0,0 +1,166 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ module Concerns
6
+ # Lets a connector address records by the identity its own system
7
+ # knows, rather than by Spree's prefixed id.
8
+ #
9
+ # Two halves:
10
+ #
11
+ # * **write** — `external_references` in the payload records the
12
+ # caller's key for the record it just wrote. Systems the payload
13
+ # does not mention keep their references, so a PIM sync never
14
+ # erases the ERP's key.
15
+ # * **read** — a member path may carry `external:<system>:<id>` in
16
+ # place of the prefixed id, so a connector that only ever learned
17
+ # the ERP's key can read, update and delete without first asking
18
+ # Spree for its id.
19
+ #
20
+ # A create carrying an `external_references` entry that already
21
+ # matches a record **updates that record** instead of failing on the
22
+ # unique index — the upsert a nightly feed needs, since a feed cannot
23
+ # know whether Spree has seen a row before.
24
+ #
25
+ # The write hangs off +serialize_resource+ rather than overriding
26
+ # +create+/+update+: several admin controllers implement those
27
+ # themselves (products and orders route through workflows), and every
28
+ # one of them reaches serialization with the saved record. Rendering
29
+ # is the one place they all agree on.
30
+ module ExternalReferences
31
+ extend ActiveSupport::Concern
32
+
33
+ # Raised when a payload's external id already names a different
34
+ # record in this store.
35
+ class ConflictingReference < StandardError; end
36
+
37
+ included do
38
+ before_action :update_instead_when_external_id_known, only: :create
39
+
40
+ rescue_from ConflictingReference do |error|
41
+ render_error(
42
+ code: 'conflicting_external_reference',
43
+ message: error.message,
44
+ status: :unprocessable_content
45
+ )
46
+ end
47
+ end
48
+
49
+ protected
50
+
51
+ # A create whose payload names an external id Spree already knows
52
+ # becomes an update of that record. Without this a re-run of the
53
+ # same feed 422s on the unique index — after persisting a duplicate
54
+ # on controllers whose +create+ builds through a workflow rather
55
+ # than +build_resource+ — which reads to a connector author as "the
56
+ # sync is broken" rather than "already imported".
57
+ #
58
+ # A before_action rather than a +build_resource+ override because
59
+ # products and orders create through workflows and never call
60
+ # +build_resource+; rendering from here halts the action, so every
61
+ # controller's +create+ gets the same upsert.
62
+ #
63
+ # Dispatches into the controller's own +update+, which is the only
64
+ # action that knows how to write that resource (orders update
65
+ # through a service, products through a workflow).
66
+ #
67
+ # A controller whose two actions permit different keys would
68
+ # silently drop a payload key the update action does not name.
69
+ # +normalize_upsert_params!+ is where such a controller reconciles
70
+ # them, and where one prepares state its update path expects; the
71
+ # default is a no-op.
72
+ def update_instead_when_external_id_known
73
+ existing = find_by_external_reference_params
74
+ return if existing.blank?
75
+
76
+ @resource = existing
77
+ authorize_resource!(@resource, :update)
78
+ normalize_upsert_params!
79
+ update
80
+ end
81
+
82
+ # Rewrites create-shaped keys into the ones this controller's
83
+ # +update+ accepts. A no-op unless the two actions disagree.
84
+ def normalize_upsert_params!; end
85
+
86
+ # `external_references` lives in its own table, so it must not
87
+ # reach the model's attribute writer.
88
+ def permitted_params
89
+ super.except(:external_references)
90
+ end
91
+
92
+ # Accepts both the `{ system => external_id }` map the serializer
93
+ # renders — so a client can send back exactly what it read — and
94
+ # the `[{ system:, external_id: }]` list a feed finds natural.
95
+ def external_reference_params
96
+ return @external_reference_params if defined?(@external_reference_params)
97
+
98
+ raw = params[:external_references]
99
+ raw = raw.to_unsafe_h if raw.respond_to?(:to_unsafe_h)
100
+ @external_reference_params = Spree::ExternalReference.normalize_references(raw)
101
+ end
102
+
103
+ # A member path may address the record by an external identity
104
+ # instead of its prefixed id, written `external:<system>:<id>` —
105
+ # e.g. `/admin/products/external:erp:MAT-100`. A connector that
106
+ # only ever learned the ERP's key can then read, update and delete
107
+ # without first querying Spree for its id.
108
+ #
109
+ # It resolves through the controller's own +scope+, so store
110
+ # scoping and authorization are exactly as they are for a prefixed
111
+ # id, and a key belonging to another store is a 404.
112
+ EXTERNAL_ID_PREFIX = 'external:'.freeze
113
+
114
+ def find_resource
115
+ return super unless external_id_lookup?
116
+
117
+ _prefix, system, external_id = params[:id].split(':', 3)
118
+ scope.with_external_id(system, external_id).take!
119
+ end
120
+
121
+ def external_id_lookup?
122
+ params[:id].to_s.start_with?(EXTERNAL_ID_PREFIX) &&
123
+ model_class.respond_to?(:with_external_id) &&
124
+ params[:id].to_s.split(':', 3).length == 3
125
+ end
126
+
127
+ def find_by_external_reference_params
128
+ return if external_reference_params.blank?
129
+ return unless model_class.respond_to?(:with_external_id)
130
+
131
+ external_reference_params.each do |entry|
132
+ match = scope.with_external_id(entry[:system], entry[:external_id]).take
133
+ return match if match.present?
134
+ end
135
+
136
+ nil
137
+ end
138
+
139
+ def serialize_resource(resource, **options)
140
+ write_external_references(resource)
141
+ super
142
+ end
143
+
144
+ def write_external_references(resource)
145
+ # Cheapest guard first: a GET must not even parse the params.
146
+ return unless request.post? || request.patch? || request.put?
147
+ return if external_reference_params.blank?
148
+ return unless resource.respond_to?(:assign_external_references)
149
+ return unless resource.persisted?
150
+
151
+ # No reload needed: set_external_id resets the association, so
152
+ # the serializer's read fetches the fresh rows.
153
+ resource.assign_external_references(external_reference_params)
154
+ rescue ActiveRecord::RecordInvalid => e
155
+ # The key already names a different record in this store. The
156
+ # resource itself is written by now, so this reports what could
157
+ # not be recorded rather than pretending the write failed.
158
+ raise Spree::Api::V3::Admin::Concerns::ExternalReferences::ConflictingReference,
159
+ e.record.errors.full_messages.to_sentence
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,31 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ # The evidence trail behind a customer's consent state — what was
6
+ # agreed, when, from where, and which document version was shown.
7
+ #
8
+ # Read-only. GDPR Art. 7(1) asks the controller to demonstrate that
9
+ # consent was given, and a record an operator can edit demonstrates
10
+ # nothing.
11
+ class ConsentRecordsController < ResourceController
12
+ scoped_resource :customers
13
+
14
+ protected
15
+
16
+ def model_class
17
+ Spree::ConsentRecord
18
+ end
19
+
20
+ def serializer_class
21
+ Spree.api.admin_consent_record_serializer
22
+ end
23
+
24
+ def scope
25
+ super.recent_first
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -3,13 +3,21 @@ module Spree
3
3
  module V3
4
4
  module Admin
5
5
  class CountriesController < ResourceController
6
- scoped_resource :settings
6
+ # Public reference data (the storefront serves the same list) — exempt
7
+ # from the key gate like `/tags`, so address forms work for any staff
8
+ # member or key. CanCanCan still applies for JWT principals via the
9
+ # staff baseline's Country read grant.
10
+ skip_scope_check!
7
11
 
8
12
  # Override base index to skip pagination — there are ~250 countries
9
13
  # and address-form dropdowns need them all at once. Pagy's global
10
14
  # max_limit (100) prevents using the paginated path for this.
15
+ #
16
+ # Countries are reference data rather than records, so this reads
17
+ # from the registry and needs no authorization beyond the admin
18
+ # credential the base controller already checked: the list is the
19
+ # same for every store and carries nothing store-specific.
11
20
  def index
12
- authorize!(:read, model_class)
13
21
  @collection = scope
14
22
  render json: { data: serialize_collection(@collection), meta: { count: @collection.size } }
15
23
  end
@@ -25,11 +33,11 @@ module Spree
25
33
  end
26
34
 
27
35
  def scope
28
- Spree::Country.all.order(:name).preload_associations_lazily
36
+ Spree::Country.all.sort_by(&:name)
29
37
  end
30
38
 
31
39
  def find_resource
32
- scope.find_by!(iso: params[:id].upcase)
40
+ Spree::Country.find_by_iso!(params[:id])
33
41
  end
34
42
  end
35
43
  end
@@ -10,6 +10,19 @@ module Spree
10
10
  class CustomFieldDefinitionsController < ResourceController
11
11
  scoped_resource :settings
12
12
 
13
+ # GET /api/v3/admin/custom_field_definitions/resource_types
14
+ #
15
+ # What a definition can be attached to, from
16
+ # `Spree.custom_fields.enabled_resources` — so a resource an
17
+ # extension registers is offered without the dashboard shipping a
18
+ # new list, and a merchant is never shown a type the server would
19
+ # then refuse.
20
+ def resource_types
21
+ authorize! :create, model_class
22
+
23
+ render json: { data: Spree::CustomFieldDefinition.enabled_resource_types }
24
+ end
25
+
13
26
  protected
14
27
 
15
28
  def model_class
@@ -20,14 +33,16 @@ module Spree
20
33
  Spree.api.admin_custom_field_definition_serializer
21
34
  end
22
35
 
23
- # `label`, `field_type`, `storefront_visible` are model-side aliases
24
- # (alias_attribute / accessors) on Spree::CustomFieldDefinition. The
25
- # API → DB column rename lands in 6.0 and this controller stays flat.
26
36
  def permitted_params
27
- params.permit(:namespace, :key, :label, :field_type,
37
+ params.permit(*model_additional_permitted_attributes, :namespace, :key, :label, :field_type,
28
38
  :resource_type, :storefront_visible,
29
39
  :searchable, :sortable)
30
40
  end
41
+
42
+ # Pure registry discovery — maps to the read scope.
43
+ def read_actions
44
+ super + %w[resource_types]
45
+ end
31
46
  end
32
47
  end
33
48
  end
@@ -9,7 +9,7 @@ module Spree
9
9
  class CustomFieldsController < ResourceController
10
10
  # POST /api/v3/admin/<parent>/<parent_id>/custom_fields
11
11
  def create
12
- @resource = @parent.metafields.new(permitted_params)
12
+ @resource = @parent.custom_fields.new(permitted_params)
13
13
  authorize_resource!(@resource, :create)
14
14
 
15
15
  if @resource.save
@@ -44,7 +44,7 @@ module Spree
44
44
  end
45
45
 
46
46
  def parent_association
47
- :metafields
47
+ :custom_fields
48
48
  end
49
49
 
50
50
  def set_parent
@@ -86,7 +86,7 @@ module Spree
86
86
  # `custom_field_definition_id` is an alias_attribute on Spree::CustomField;
87
87
  # AR resolves the prefixed-ID and the alias to the canonical FK on assign.
88
88
  def permitted_params
89
- params.permit(:custom_field_definition_id, :value)
89
+ params.permit(*model_additional_permitted_attributes, :custom_field_definition_id, :value)
90
90
  end
91
91
 
92
92
  def update_permitted_params
@@ -104,9 +104,9 @@ module Spree
104
104
  # and `'category'` because the routes expose taxons as categories
105
105
  # (5.5 rename) while the model's element is still `'taxon'`.
106
106
  def parent_route_map
107
- @parent_route_map ||= Spree.metafields.enabled_resources.each_with_object({}) do |klass, m|
107
+ @parent_route_map ||= Spree.custom_fields.enabled_resources.each_with_object({}) do |klass, m|
108
108
  m[klass.model_name.element.to_s] = klass.name
109
- end.merge('customer' => Spree.user_class.name, 'category' => 'Spree::Taxon')
109
+ end.merge('customer' => Spree.customer_class.name, 'category' => 'Spree::Category')
110
110
  end
111
111
 
112
112
  # Returns the first segment whose `<segment>_id` is present in params,
@@ -22,7 +22,7 @@ module Spree
22
22
  end
23
23
 
24
24
  def permitted_params
25
- params.permit(:name, :description, customer_ids: [])
25
+ params.permit(*model_additional_permitted_attributes, :name, :description, customer_ids: [])
26
26
  end
27
27
  end
28
28
  end
@@ -7,7 +7,7 @@ module Spree
7
7
 
8
8
  # POST /api/v3/admin/customers/:customer_id/addresses
9
9
  def create
10
- authorize_resource!(Spree::Address.new(user_id: @parent.id), :create)
10
+ authorize_resource!(Spree::Address.new(owner: @parent), :create)
11
11
 
12
12
  result = Spree.address_create_service.call(
13
13
  address_params: address_attrs,
@@ -68,18 +68,18 @@ module Spree
68
68
  params.permit(
69
69
  :firstname, :lastname, :first_name, :last_name,
70
70
  :address1, :address2, :city,
71
- :country_iso, :state_abbr, :country_id, :state_id,
71
+ :country_code, :state_code,
72
72
  :zipcode, :postal_code, :phone, :alternative_phone,
73
73
  :state_name, :company, :label, :quick_checkout
74
74
  )
75
75
  end
76
76
 
77
77
  def default_billing_flag
78
- ActiveModel::Type::Boolean.new.cast(params[:is_default_billing])
78
+ params[:is_default_billing].to_b
79
79
  end
80
80
 
81
81
  def default_shipping_flag
82
- ActiveModel::Type::Boolean.new.cast(params[:is_default_shipping])
82
+ params[:is_default_shipping].to_b
83
83
  end
84
84
  end
85
85
  end
@@ -21,7 +21,7 @@ module Spree
21
21
  # global in Spree (`User.for_store` is a no-op), so the ability is
22
22
  # the only boundary here.
23
23
  def set_parent
24
- @parent = Spree.user_class.
24
+ @parent = Spree.customer_class.
25
25
  accessible_by(current_ability, parent_ability_action).
26
26
  find_by_prefix_id!(params[:customer_id])
27
27
  end
@@ -14,7 +14,6 @@ module Spree
14
14
  @resource = @parent.store_credits.new(create_attrs)
15
15
  @resource.created_by = try_spree_current_user
16
16
  @resource.store ||= current_store
17
- @resource.category ||= Spree::StoreCreditCategory.first
18
17
  authorize_resource!(@resource, :create)
19
18
 
20
19
  if @resource.save
@@ -84,11 +83,11 @@ module Spree
84
83
  private
85
84
 
86
85
  def create_attrs
87
- params.permit(:amount, :currency, :category_id, :memo).to_h
86
+ params.permit(:amount, :currency, :memo).to_h
88
87
  end
89
88
 
90
89
  def update_attrs
91
- params.permit(:memo, :category_id, :amount).to_h
90
+ params.permit(:memo, :amount).to_h
92
91
  end
93
92
  end
94
93
  end
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ module Customers
6
+ class TaxIdentifiersController < BaseController
7
+ scoped_resource :customers
8
+
9
+ include Spree::Api::V3::TaxIdentifierValidation
10
+
11
+ # Re-declaring the filter replaces the inherited options, so the
12
+ # standard actions have to be listed alongside the custom one.
13
+ before_action :set_resource, only: [:show, :update, :destroy, :validate]
14
+
15
+ # POST /api/v3/admin/customers/:customer_id/tax_identifiers/:id/validate
16
+ #
17
+ # Re-asks the registry. Manual because a registry answers only "valid
18
+ # now": a number verified last year may have been deregistered since,
19
+ # and staff need a way to check without editing the row.
20
+
21
+ protected
22
+
23
+ def model_class
24
+ Spree::TaxIdentifier
25
+ end
26
+
27
+ def serializer_class
28
+ Spree.api.admin_tax_identifier_serializer
29
+ end
30
+
31
+ def scope
32
+ @parent.tax_identifiers
33
+ end
34
+
35
+ def permitted_params
36
+ params.permit(:kind, :value)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -7,17 +7,18 @@ module Spree
7
7
 
8
8
  scoped_resource :customers
9
9
 
10
+ # Re-declaring a `before_action` for the same method REPLACES the
11
+ # inherited registration rather than adding to it, so the inherited
12
+ # actions have to be repeated here or show/update/destroy silently
13
+ # lose their record.
14
+ before_action :set_resource, only: [:show, :update, :destroy, :export, :anonymize]
10
15
  before_action :require_ids!, only: [:bulk_add_to_groups, :bulk_remove_from_groups]
11
16
 
12
17
  def create
13
- @resource = Spree.user_class.new(permitted_params)
14
- # Admin-created customers don't pick a password upfront — they
15
- # claim the account via password reset later.
16
- # `Spree::UserMethods` exposes `skip_password_validation` so
17
- # Devise's `:validatable` lets a nil credential through on this
18
- # code path. Storefront registration never sets the flag, so
19
- # customer self-signup still requires a password.
20
- @resource.skip_password_validation = true if @resource.password.blank?
18
+ @resource = Spree.customer_class.new(permitted_params)
19
+ # Admin-created customers may be created without a password; they
20
+ # claim the account via password reset later (the model does not
21
+ # enforce password presence).
21
22
  authorize!(:create, @resource)
22
23
 
23
24
  if @resource.save
@@ -30,6 +31,12 @@ module Spree
30
31
  def update
31
32
  authorize_resource!(@resource)
32
33
 
34
+ # A staff member is making this change, so a marketing-consent flip
35
+ # is recorded as theirs. Left unset it would stamp `account`, which
36
+ # says the person changed their own permission — evidence of a
37
+ # gesture they never made.
38
+ @resource.consent_source = Spree::ConsentRecord::ADMIN
39
+
33
40
  if @resource.update(permitted_params)
34
41
  render json: serialize_resource(@resource.reload)
35
42
  else
@@ -49,6 +56,88 @@ module Spree
49
56
  )
50
57
  end
51
58
 
59
+ # POST /api/v3/admin/customers/:id/anonymize
60
+ #
61
+ # Erases the customer's personal data while leaving the financial
62
+ # record intact. This is what a merchant runs when an erasure request
63
+ # arrives by email — which is how most of them arrive, from people
64
+ # who often can no longer sign in.
65
+ #
66
+ # Irreversible, so it is its own action rather than a flag on update.
67
+ def anonymize
68
+ authorize_resource!(@resource)
69
+
70
+ # Recorded like the export beside it. The erasure itself is the
71
+ # obligation and runs whatever happens to the record, but a
72
+ # merchant answering an emailed request should not have to
73
+ # remember they did — the request log is what an Art. 30 enquiry
74
+ # reads, and an erasure that left only an event was invisible to it.
75
+ data_request = open_erasure_record
76
+
77
+ # Through the dependency, not the class: a host app that swaps the
78
+ # anonymizer in — for a legal hold, or to reach its own tables —
79
+ # must get the same erasure whoever asked for it. Naming the class
80
+ # here would apply their override to a customer's own request and
81
+ # skip it when staff answer the same request from the admin.
82
+ result = Spree.customer_anonymize_workflow.call(
83
+ customer: @resource,
84
+ store: current_store,
85
+ requested_by: try_spree_current_user
86
+ )
87
+
88
+ unless result.success?
89
+ data_request&.update(status: 'failed', error_message: result.error.to_s.first(1000))
90
+ return render_result_error(result)
91
+ end
92
+
93
+ data_request&.update(status: 'completed', completed_at: Time.current)
94
+
95
+ render json: serialize_resource(@resource.reload)
96
+ end
97
+
98
+ # GET /api/v3/admin/customers/:id/export
99
+ #
100
+ # The customer's data as JSON, for answering a subject access request
101
+ # the merchant received directly. Rendered inline rather than queued:
102
+ # a staff member is waiting on it, and unlike the storefront path
103
+ # there is no unauthenticated caller to rate-limit.
104
+ def export
105
+ authorize_resource!(@resource)
106
+ return unless authorized_for_export?
107
+
108
+ if @resource.anonymized?
109
+ return render_error(
110
+ code: ERROR_CODES[:validation_error],
111
+ message: Spree.t('data_request_errors.already_anonymized'),
112
+ status: :unprocessable_content
113
+ )
114
+ end
115
+
116
+ # Its own record, never an existing one. `DataRequests::Create`
117
+ # returns whatever request is in flight for this customer, and
118
+ # completing that here would close their request without ever
119
+ # delivering their file — the queued job would then refuse it as no
120
+ # longer pending. Its `requested_by_id: nil` filter does not help:
121
+ # it scopes to rows the customer opened, which is exactly the row
122
+ # that must be left alone.
123
+ data_request = Spree::DataRequest.create!(
124
+ store: current_store,
125
+ customer: @resource,
126
+ kind: Spree::DataRequest::ACCESS,
127
+ email: @resource.email,
128
+ requested_by: try_spree_current_user
129
+ )
130
+
131
+ # The request row is opened first: an Art. 15 response should leave
132
+ # the same trace whoever produced it, and building through the
133
+ # workflow is what runs the `extend_payload` hook a host app relies
134
+ # on to complete the document.
135
+ payload = Spree::DataRequests::Fulfill.payload_for(data_request)
136
+ data_request.update(status: 'completed', completed_at: Time.current)
137
+
138
+ render json: payload
139
+ end
140
+
52
141
  # Bulk add the given customers to the given groups. Idempotent —
53
142
  # customers already in a group are skipped at the model layer.
54
143
  def bulk_add_to_groups
@@ -63,7 +152,7 @@ module Spree
63
152
  protected
64
153
 
65
154
  def model_class
66
- Spree.user_class
155
+ Spree.customer_class
67
156
  end
68
157
 
69
158
  def serializer_class
@@ -74,10 +163,99 @@ module Spree
74
163
  super.with_order_aggregates
75
164
  end
76
165
 
166
+ # Producing the export reads the customer, so it is a read for the
167
+ # key gate and for CanCanCan alike. The latter needs saying twice:
168
+ # `read_actions` settles the required API-key scope, while
169
+ # `authorize_resource!` below maps the action onto an ability a role
170
+ # actually grants — CanCanCan's `:read` alias covers only index and
171
+ # show, so a staffer with read access would otherwise be refused.
172
+ def read_actions
173
+ super + ['export']
174
+ end
175
+
176
+ # Its own row rather than one the customer has in flight, for the
177
+ # same reason the export opens its own: completing theirs here would
178
+ # close a request whose file was never delivered.
179
+ #
180
+ # @return [Spree::DataRequest, nil] nil when the record cannot be
181
+ # written — the erasure is the obligation and still runs
182
+ def open_erasure_record
183
+ Spree::DataRequest.create(
184
+ store: current_store,
185
+ customer: @resource,
186
+ kind: Spree::DataRequest::ERASURE,
187
+ email: @resource.email,
188
+ requested_by: try_spree_current_user,
189
+ status: 'processing'
190
+ ).presence
191
+ rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique => e
192
+ Rails.logger.warn { "[Spree] Could not record erasure request: #{e.message}" }
193
+ nil
194
+ end
195
+
196
+ # A subject access export carries the customer's order history, which
197
+ # is otherwise gated on `read_orders`. The controller's own scope only
198
+ # covers `read_customers`, so aggregating the two behind one key would
199
+ # hand order data to a role that was never granted it.
200
+ #
201
+ # @return [Boolean] false when the response has already been rendered
202
+ # Everything the subject access response gathers, and the permission
203
+ # that guards it elsewhere in the API. Seeing a customer's name is not
204
+ # the same as downloading their order history, their saved cards and
205
+ # their balances in one file, so the export asks for each of them.
206
+ EXPORT_PERMISSIONS = %w[
207
+ read_orders
208
+ read_payments
209
+ read_store_credits
210
+ read_gift_cards
211
+ ].freeze
212
+
213
+ def authorized_for_export?
214
+ missing = EXPORT_PERMISSIONS.reject { |permission| holds_permission?(permission) }
215
+ return true if missing.empty?
216
+
217
+ render_error(
218
+ code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:access_denied],
219
+ message: "Missing permission: #{missing.first}",
220
+ status: :forbidden,
221
+ details: { required_permission: missing.first }
222
+ )
223
+ false
224
+ end
225
+
226
+ # Mirrors the key gate's two principals: a secret key carries scopes,
227
+ # a signed-in staffer carries their roles' catalog keys.
228
+ #
229
+ # @param key [String]
230
+ # @return [Boolean]
231
+ def holds_permission?(key)
232
+ return current_api_key.has_scope?(key) if scope_limited_principal?
233
+
234
+ ability = current_ability
235
+ return true unless ability.respond_to?(:permission_keys)
236
+
237
+ ability.permission_keys.include?(key)
238
+ end
239
+
240
+ # `export` maps to `:show`; `anonymize` is a destructive write, so it
241
+ # maps to `:destroy` rather than `:update` — a role that may correct
242
+ # a customer's name should not thereby be able to erase their history.
243
+ def authorize_resource!(resource = @resource, action = action_name.to_sym)
244
+ mapped = case action
245
+ when :export then :show
246
+ when :anonymize then :destroy
247
+ else action
248
+ end
249
+
250
+ authorize!(mapped, resource || model_class)
251
+ end
252
+
77
253
  # `customer_groups` is preloaded because the serializer's always-on
78
- # `customer_group_ids` attribute reads it for every row.
254
+ # `customer_group_ids` attribute reads it for every row. `companies`
255
+ # is not: it only renders behind `?expand=companies`, where
256
+ # ar_lazy_preload already batches it into one query for the page.
79
257
  def collection_includes
80
- [:rich_text_internal_note, :customer_groups, taggings: :tag]
258
+ [:customer_groups, taggings: :tag]
81
259
  end
82
260
 
83
261
  private
@@ -95,6 +273,7 @@ module Spree
95
273
 
96
274
  def permitted_params
97
275
  params.permit(
276
+ *model_additional_permitted_attributes,
98
277
  :email, :first_name, :last_name, :phone,
99
278
  :password, :password_confirmation, :selected_locale,
100
279
  :avatar, :accepts_email_marketing, :internal_note,