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.
- checksums.yaml +4 -4
- data/LICENSE +28 -0
- data/Rakefile +1 -1
- data/app/controllers/concerns/spree/api/v3/address_params.rb +17 -0
- data/app/controllers/concerns/spree/api/v3/admin/product_listing.rb +46 -0
- data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +110 -0
- data/app/controllers/concerns/spree/api/v3/admin/receivable_actions.rb +68 -0
- data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +27 -0
- data/app/controllers/concerns/spree/api/v3/admin/role_grant_guard.rb +69 -33
- data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +86 -0
- data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +97 -0
- data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +12 -6
- data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +91 -0
- data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +20 -5
- data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +41 -5
- data/app/controllers/concerns/spree/api/v3/authentication_strategies.rb +48 -0
- data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +4 -6
- data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +52 -16
- data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +37 -0
- data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +41 -0
- data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +35 -0
- data/app/controllers/concerns/spree/api/v3/error_handler.rb +53 -11
- data/app/controllers/concerns/spree/api/v3/idempotent.rb +10 -4
- data/app/controllers/concerns/spree/api/v3/items_payload.rb +54 -0
- data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +23 -3
- data/app/controllers/concerns/spree/api/v3/key_store_context.rb +31 -0
- data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +3 -3
- data/app/controllers/concerns/spree/api/v3/order_lock.rb +22 -3
- data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +112 -0
- data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +105 -0
- data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +117 -0
- data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +157 -0
- data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +76 -0
- data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +116 -0
- data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +128 -0
- data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +7 -4
- data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +42 -0
- data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +40 -6
- data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +80 -26
- data/app/controllers/concerns/spree/api/v3/seller/auth_cookies.rb +62 -0
- data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +127 -0
- data/app/controllers/concerns/spree/api/v3/seller_authentication.rb +40 -0
- data/app/controllers/concerns/spree/api/v3/storefront_access.rb +38 -0
- data/app/controllers/concerns/spree/api/v3/streams_shipping_label.rb +37 -0
- data/app/controllers/concerns/spree/api/v3/tax_identifier_validation.rb +41 -0
- data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +11 -14
- data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +18 -9
- data/app/controllers/spree/api/v3/admin/auth_controller.rb +138 -22
- data/app/controllers/spree/api/v3/admin/base_controller.rb +2 -0
- data/app/controllers/spree/api/v3/admin/catalog_assignments_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/catalogs/base_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/catalogs/products_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +191 -0
- data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +28 -41
- data/app/controllers/spree/api/v3/admin/categories_controller.rb +16 -7
- data/app/controllers/spree/api/v3/admin/channels_controller.rb +50 -2
- data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/claims_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/collection_rules_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +101 -0
- data/app/controllers/spree/api/v3/admin/collections_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/commission_lines_controller.rb +39 -0
- data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +174 -0
- data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +65 -0
- data/app/controllers/spree/api/v3/admin/companies/base_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +137 -0
- data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +46 -0
- data/app/controllers/spree/api/v3/admin/companies_controller.rb +59 -0
- data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +166 -0
- data/app/controllers/spree/api/v3/admin/consent_records_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/countries_controller.rb +12 -4
- data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +19 -4
- data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +5 -5
- data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +4 -4
- data/app/controllers/spree/api/v3/admin/customers/base_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +2 -3
- data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/admin/customers_controller.rb +190 -11
- data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +24 -20
- data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +60 -0
- data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +54 -0
- data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +114 -0
- data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +243 -0
- data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +80 -0
- data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +116 -0
- data/app/controllers/spree/api/v3/admin/digital_links_controller.rb +48 -0
- data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +17 -3
- data/app/controllers/spree/api/v3/admin/exchanges_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/exports_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +3 -2
- data/app/controllers/spree/api/v3/admin/imports_controller.rb +71 -8
- data/app/controllers/spree/api/v3/admin/integrations_controller.rb +67 -0
- data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +5 -5
- data/app/controllers/spree/api/v3/admin/invitations_controller.rb +5 -1
- data/app/controllers/spree/api/v3/admin/locales_controller.rb +3 -1
- data/app/controllers/spree/api/v3/admin/markets_controller.rb +9 -5
- data/app/controllers/spree/api/v3/admin/me_controller.rb +4 -30
- data/app/controllers/spree/api/v3/admin/media_controller.rb +88 -38
- data/app/controllers/spree/api/v3/admin/media_library_controller.rb +156 -0
- data/app/controllers/spree/api/v3/admin/option_types_controller.rb +1 -0
- data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +43 -0
- data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +86 -0
- data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +99 -0
- data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +62 -0
- data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +83 -0
- data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +45 -67
- data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +40 -22
- data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +36 -18
- data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +39 -18
- data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +70 -0
- data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/orders/tax_identifiers_controller.rb +41 -0
- data/app/controllers/spree/api/v3/admin/orders/tax_lines_controller.rb +32 -0
- data/app/controllers/spree/api/v3/admin/orders_controller.rb +164 -33
- data/app/controllers/spree/api/v3/admin/package_types_controller.rb +39 -0
- data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +15 -4
- data/app/controllers/spree/api/v3/admin/payout_providers_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/permissions_controller.rb +30 -0
- data/app/controllers/spree/api/v3/admin/policies_controller.rb +42 -0
- data/app/controllers/spree/api/v3/admin/price_lists/products_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +43 -29
- data/app/controllers/spree/api/v3/admin/prices_controller.rb +41 -4
- data/app/controllers/spree/api/v3/admin/product_types_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +148 -0
- data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +24 -3
- data/app/controllers/spree/api/v3/admin/products_controller.rb +149 -33
- data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +6 -2
- data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -5
- data/app/controllers/spree/api/v3/admin/purchase_orders/stock_receipts_controller.rb +32 -0
- data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +161 -0
- data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +45 -0
- data/app/controllers/spree/api/v3/admin/reporting_controller.rb +95 -0
- data/app/controllers/spree/api/v3/admin/resource_controller.rb +27 -10
- data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/returns_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/roles_controller.rb +50 -6
- data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +83 -0
- data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +139 -0
- data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +115 -0
- data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +36 -0
- data/app/controllers/spree/api/v3/admin/sellers/balances_controller.rb +44 -0
- data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +77 -0
- data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/sellers/team_controller.rb +64 -0
- data/app/controllers/spree/api/v3/admin/sellers_controller.rb +197 -0
- data/app/controllers/spree/api/v3/admin/setup_controller.rb +239 -0
- data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +172 -0
- data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +3 -2
- data/app/controllers/spree/api/v3/admin/stock_movements_controller.rb +37 -0
- data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/stock_transfers/stock_receipts_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +134 -38
- data/app/controllers/spree/api/v3/admin/store_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/store_credits/events_controller.rb +47 -0
- data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +87 -0
- data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +30 -0
- data/app/controllers/spree/api/v3/admin/tags_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +4 -0
- data/app/controllers/spree/api/v3/admin/tax_providers_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +37 -9
- data/app/controllers/spree/api/v3/admin/translations_controller.rb +10 -5
- data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +150 -0
- data/app/controllers/spree/api/v3/admin/variants_controller.rb +11 -4
- data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +1 -1
- data/app/controllers/spree/api/v3/base_controller.rb +74 -16
- data/app/controllers/spree/api/v3/resource_controller.rb +170 -39
- data/app/controllers/spree/api/v3/seller/auth_controller.rb +169 -0
- data/app/controllers/spree/api/v3/seller/balances_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/base_controller.rb +25 -0
- data/app/controllers/spree/api/v3/seller/claim_reasons_controller.rb +20 -0
- data/app/controllers/spree/api/v3/seller/countries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +265 -0
- data/app/controllers/spree/api/v3/seller/delivery_profiles_controller.rb +65 -0
- data/app/controllers/spree/api/v3/seller/delivery_zones_controller.rb +41 -0
- data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +21 -0
- data/app/controllers/spree/api/v3/seller/exports_controller.rb +195 -0
- data/app/controllers/spree/api/v3/seller/import_rows_controller.rb +49 -0
- data/app/controllers/spree/api/v3/seller/imports_controller.rb +317 -0
- data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +152 -0
- data/app/controllers/spree/api/v3/seller/invitations_controller.rb +71 -0
- data/app/controllers/spree/api/v3/seller/me_controller.rb +72 -0
- data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +111 -0
- data/app/controllers/spree/api/v3/seller/order_cancellation_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/seller/orders/base_controller.rb +44 -0
- data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +45 -0
- data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +50 -0
- data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +79 -0
- data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +55 -0
- data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +82 -0
- data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +44 -0
- data/app/controllers/spree/api/v3/seller/orders_controller.rb +199 -0
- data/app/controllers/spree/api/v3/seller/package_types_controller.rb +100 -0
- data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +155 -0
- data/app/controllers/spree/api/v3/seller/payouts_controller.rb +47 -0
- data/app/controllers/spree/api/v3/seller/policies_controller.rb +57 -0
- data/app/controllers/spree/api/v3/seller/product_types_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/products_controller.rb +394 -0
- data/app/controllers/spree/api/v3/seller/profile_controller.rb +137 -0
- data/app/controllers/spree/api/v3/seller/reasons_controller.rb +45 -0
- data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +95 -0
- data/app/controllers/spree/api/v3/seller/resource_controller.rb +75 -0
- data/app/controllers/spree/api/v3/seller/return_reasons_controller.rb +20 -0
- data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +56 -0
- data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +48 -0
- data/app/controllers/spree/api/v3/seller/team_controller.rb +103 -0
- data/app/controllers/spree/api/v3/seller/tracking_carriers_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/transfers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/store/account/companies_controller.rb +42 -0
- data/app/controllers/spree/api/v3/store/auth_controller.rb +21 -34
- data/app/controllers/spree/api/v3/store/base_controller.rb +4 -0
- data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +24 -2
- data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +41 -15
- data/app/controllers/spree/api/v3/store/carts/items_controller.rb +53 -20
- data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +36 -20
- data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +111 -0
- data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +2 -2
- data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +96 -0
- data/app/controllers/spree/api/v3/store/carts_controller.rb +57 -12
- data/app/controllers/spree/api/v3/store/categories_controller.rb +6 -3
- data/app/controllers/spree/api/v3/store/collections/products_controller.rb +59 -0
- data/app/controllers/spree/api/v3/store/collections_controller.rb +36 -0
- data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +81 -0
- data/app/controllers/spree/api/v3/store/companies/base_controller.rb +24 -0
- data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +50 -0
- data/app/controllers/spree/api/v3/store/companies/members_controller.rb +66 -0
- data/app/controllers/spree/api/v3/store/companies/orders_controller.rb +28 -0
- data/app/controllers/spree/api/v3/store/companies_controller.rb +47 -0
- data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +90 -0
- data/app/controllers/spree/api/v3/store/countries_controller.rb +8 -6
- data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +3 -1
- data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +78 -0
- data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +52 -0
- data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +6 -0
- data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +7 -3
- data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +3 -3
- data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -3
- data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +91 -0
- data/app/controllers/spree/api/v3/store/customers_controller.rb +26 -31
- data/app/controllers/spree/api/v3/store/data_feeds_controller.rb +11 -0
- data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +58 -0
- data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +108 -0
- data/app/controllers/spree/api/v3/store/digital_links_controller.rb +105 -0
- data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +5 -9
- data/app/controllers/spree/api/v3/store/markets_controller.rb +4 -4
- data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +8 -9
- data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +94 -0
- data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +116 -0
- data/app/controllers/spree/api/v3/store/orders/tax_identifiers_controller.rb +46 -0
- data/app/controllers/spree/api/v3/store/orders_controller.rb +12 -15
- data/app/controllers/spree/api/v3/store/products/filters_controller.rb +10 -3
- data/app/controllers/spree/api/v3/store/products_controller.rb +25 -6
- data/app/controllers/spree/api/v3/store/resource_controller.rb +2 -0
- data/app/controllers/spree/api/v3/store/sellers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +9 -6
- data/app/controllers/spree/api/v3/store/wishlists_controller.rb +3 -3
- data/app/controllers/spree/api/v3/webhooks/fulfillments_controller.rb +88 -0
- data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +5 -2
- data/app/controllers/spree/api/v3/webhooks/payouts_controller.rb +61 -0
- data/app/models/spree/api/data_request_urls.rb +25 -0
- data/app/models/spree/api/digital_link_urls.rb +26 -0
- data/app/serializers/spree/api/v3/address_serializer.rb +17 -5
- data/app/serializers/spree/api/v3/admin/actor_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/address_serializer.rb +27 -4
- data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +13 -10
- data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +15 -2
- data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/cart_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/admin/catalog_product_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +38 -0
- data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/catalog_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/category_serializer.rb +3 -2
- data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -1
- data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/claim_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/collection_rule_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/admin/collection_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +67 -0
- data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +69 -0
- data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +61 -0
- data/app/serializers/spree/api/v3/admin/company_invitation_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/company_membership_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/company_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/concerns/external_references_attribute.rb +33 -0
- data/app/serializers/spree/api/v3/admin/consent_record_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/country_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/customer_serializer.rb +23 -22
- data/app/serializers/spree/api/v3/admin/dashboard_counter_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +66 -1
- data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/delivery_profile_serializer.rb +65 -0
- data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +10 -1
- data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/admin/delivery_zone_member_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -4
- data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/export_serializer.rb +20 -1
- data/app/serializers/spree/api/v3/admin/fee_serializer.rb +14 -0
- data/app/serializers/spree/api/v3/admin/freight_summary_line_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/freight_summary_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +31 -9
- data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -3
- data/app/serializers/spree/api/v3/admin/import_serializer.rb +15 -2
- data/app/serializers/spree/api/v3/admin/integration_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +4 -4
- data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +46 -5
- data/app/serializers/spree/api/v3/admin/market_serializer.rb +5 -1
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +50 -2
- data/app/serializers/spree/api/v3/admin/membership_product_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +126 -31
- data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +8 -2
- data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -0
- data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/admin/permission_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/policy_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/admin/price_list_product_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +20 -8
- data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -12
- data/app/serializers/spree/api/v3/admin/price_serializer.rb +3 -0
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +54 -8
- data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/product_type_custom_field_definition_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +6 -12
- data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +17 -15
- data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +80 -0
- data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +94 -0
- data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/admin/refund_serializer.rb +6 -5
- data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +72 -0
- data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/return_serializer.rb +58 -0
- data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
- data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_serializer.rb +68 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/seller_serializer.rb +92 -0
- data/app/serializers/spree/api/v3/admin/seller_team_member_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +82 -0
- data/app/serializers/spree/api/v3/admin/state_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +65 -0
- data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +20 -4
- data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +116 -0
- data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +5 -5
- data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +36 -16
- data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +42 -7
- data/app/serializers/spree/api/v3/admin/store_serializer.rb +65 -1
- data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +67 -0
- data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +43 -0
- data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +49 -8
- data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/base_serializer.rb +61 -2
- data/app/serializers/spree/api/v3/cart_serializer.rb +90 -12
- data/app/serializers/spree/api/v3/category_serializer.rb +3 -3
- data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/claim_reason_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/claim_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/collection_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/company_invitation_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/company_membership_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/company_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/custom_field_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/customer_serializer.rb +9 -1
- data/app/serializers/spree/api/v3/data_request_event_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/data_request_serializer.rb +40 -0
- data/app/serializers/spree/api/v3/delivery_method_serializer.rb +12 -2
- data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +34 -17
- data/app/serializers/spree/api/v3/delivery_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/delivery_zone_serializer.rb +13 -0
- data/app/serializers/spree/api/v3/digital_asset_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/digital_link_serializer.rb +6 -2
- data/app/serializers/spree/api/v3/discount_serializer.rb +21 -7
- data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/exchange_serializer.rb +61 -0
- data/app/serializers/spree/api/v3/fee_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/freight_summary_serializer.rb +38 -0
- data/app/serializers/spree/api/v3/fulfillment_serializer.rb +28 -15
- data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/import_serializer.rb +18 -4
- data/app/serializers/spree/api/v3/invitation_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/line_item_serializer.rb +18 -1
- data/app/serializers/spree/api/v3/market_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/{asset_serializer.rb → media_event_serializer.rb} +4 -4
- data/app/serializers/spree/api/v3/media_serializer.rb +48 -7
- data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/option_type_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/order_group_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/order_serializer.rb +58 -6
- data/app/serializers/spree/api/v3/payment_method_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/payment_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/payment_session_serializer.rb +10 -3
- data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/policy_serializer.rb +7 -2
- data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/product_serializer.rb +42 -10
- data/app/serializers/spree/api/v3/product_type_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/refund_serializer.rb +9 -3
- data/app/serializers/spree/api/v3/return_line_item_serializer.rb +42 -0
- data/app/serializers/spree/api/v3/return_reason_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/return_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/seller/balance_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/seller/claim_serializer.rb +25 -0
- data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/seller/delivery_profile_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/seller/export_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +43 -0
- data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +76 -0
- data/app/serializers/spree/api/v3/seller/import_mapping_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/seller/import_row_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/import_serializer.rb +77 -0
- data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/media_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/seller/order_serializer.rb +119 -0
- data/app/serializers/spree/api/v3/seller/package_type_serializer.rb +52 -0
- data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/seller/payout_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/seller/policy_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/seller/product_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/seller/product_type_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/profile_serializer.rb +77 -0
- data/app/serializers/spree/api/v3/seller/reason_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/seller/requirement_custom_field_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/seller/requirement_submission_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/seller/return_serializer.rb +51 -0
- data/app/serializers/spree/api/v3/seller/shipping_label_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/seller/stock_level_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/tax_identifier_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/seller/team_member_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/seller/variant_serializer.rb +71 -0
- data/app/serializers/spree/api/v3/seller_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/{stock_item_serializer.rb → stock_level_serializer.rb} +5 -5
- data/app/serializers/spree/api/v3/stock_location_serializer.rb +11 -7
- data/app/serializers/spree/api/v3/stock_movement_serializer.rb +8 -15
- data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +6 -6
- data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/supplier_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/tax_identifier_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/tax_line_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/variant_serializer.rb +52 -2
- data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +6 -6
- data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
- data/app/services/spree/api/v3/filters_aggregator.rb +14 -12
- data/app/services/spree/webhooks/deliver_webhook.rb +62 -26
- data/app/subscribers/spree/webhook_event_subscriber.rb +9 -5
- data/config/brakeman.ignore +1 -1
- data/config/initializers/typelizer.rb +51 -4
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +730 -22
- data/lib/spree/api/configuration.rb +19 -19
- data/lib/spree/api/dependencies.rb +174 -227
- data/lib/spree/api/engine.rb +6 -0
- data/lib/spree/api/openapi/schema_helper.rb +179 -13
- data/lib/spree/api/testing_support/v3/base.rb +45 -15
- data/lib/spree/api.rb +10 -4
- data/lib/typelizer/open_enums.rb +35 -0
- metadata +342 -27
- data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +0 -25
- data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +0 -42
- data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +0 -21
- data/app/controllers/spree/api/v3/store/digitals_controller.rb +0 -38
- data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +0 -24
- data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +0 -143
- data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +0 -15
- data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +0 -19
- data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +0 -34
- data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +0 -19
- data/app/serializers/spree/api/v3/customer_return_serializer.rb +0 -17
- data/app/serializers/spree/api/v3/digital_serializer.rb +0 -17
- data/app/serializers/spree/api/v3/reimbursement_serializer.rb +0 -27
- data/app/serializers/spree/api/v3/report_serializer.rb +0 -34
- data/app/serializers/spree/api/v3/return_authorization_serializer.rb +0 -31
- data/app/serializers/spree/api/v3/return_item_serializer.rb +0 -53
- 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
|
-
|
|
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.
|
|
36
|
+
Spree::Country.all.sort_by(&:name)
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
def find_resource
|
|
32
|
-
|
|
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.
|
|
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
|
-
:
|
|
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.
|
|
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.
|
|
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,
|
|
@@ -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(
|
|
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
|
-
:
|
|
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
|
-
|
|
78
|
+
params[:is_default_billing].to_b
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def default_shipping_flag
|
|
82
|
-
|
|
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.
|
|
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, :
|
|
86
|
+
params.permit(:amount, :currency, :memo).to_h
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
def update_attrs
|
|
91
|
-
params.permit(:memo, :
|
|
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.
|
|
14
|
-
# Admin-created customers
|
|
15
|
-
# claim the account via password reset later
|
|
16
|
-
#
|
|
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.
|
|
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
|
-
[:
|
|
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,
|