spree_api 5.6.1 → 6.0.0.beta1
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 +9 -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 +16 -7
- 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 +157 -32
- 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 +231 -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 +65 -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 +59 -16
- data/app/controllers/spree/api/v3/resource_controller.rb +154 -38
- 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/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 +1 -1
- 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 +29 -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 +35 -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 +19 -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 +131 -19
- 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 +0 -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 +59 -0
- data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
- data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +33 -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 +49 -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 +63 -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 +39 -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 +2 -7
- data/lib/spree/api/dependencies.rb +173 -227
- 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 +341 -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
|
@@ -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,
|
|
@@ -2,23 +2,31 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
|
+
# Point-in-time counts registered on Spree.reporting: what needs the
|
|
6
|
+
# merchant's attention right now, for the home screen's card and the
|
|
7
|
+
# sidebar's badges. Time-series analytics live in the semantic
|
|
8
|
+
# reporting endpoint (ReportingController).
|
|
5
9
|
class DashboardController < Admin::BaseController
|
|
6
|
-
|
|
10
|
+
include ReportingAuthorization
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
def analytics
|
|
10
|
-
date_from = (params[:date_from] || 30.days.ago).to_time.beginning_of_day
|
|
11
|
-
date_to = (params[:date_to] || Time.current).to_time.end_of_day
|
|
12
|
-
currency = params[:currency] || current_store.default_currency
|
|
12
|
+
scoped_resource :dashboard
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# GET /api/v3/admin/dashboard/counters
|
|
15
|
+
#
|
|
16
|
+
# Filtered to the counters this caller may read, so a limited role
|
|
17
|
+
# gets a shorter list rather than a refused card.
|
|
18
|
+
def counters
|
|
19
|
+
channel = requested_channel
|
|
20
|
+
evaluated = Spree::Reporting::Counters.new(
|
|
15
21
|
store: current_store,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
params: serializer_params
|
|
22
|
+
channel: channel,
|
|
23
|
+
allowed: ->(counter) { member_allowed?(counter) }
|
|
19
24
|
)
|
|
20
25
|
|
|
21
|
-
render json:
|
|
26
|
+
render json: {
|
|
27
|
+
channel_id: channel&.prefixed_id,
|
|
28
|
+
counters: DashboardCounterSerializer.new(evaluated.to_a).serializable_hash
|
|
29
|
+
}
|
|
22
30
|
end
|
|
23
31
|
|
|
24
32
|
private
|
|
@@ -27,15 +35,11 @@ module Spree
|
|
|
27
35
|
'read'
|
|
28
36
|
end
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
user: current_user,
|
|
36
|
-
includes: [],
|
|
37
|
-
expand: []
|
|
38
|
-
}
|
|
38
|
+
# Optional channel scoping — omitted means all channels.
|
|
39
|
+
def requested_channel
|
|
40
|
+
return if params[:channel_id].blank?
|
|
41
|
+
|
|
42
|
+
current_store.channels.find_by_prefix_id!(params[:channel_id])
|
|
39
43
|
end
|
|
40
44
|
end
|
|
41
45
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# The store's log of GDPR data subject requests — what was asked for,
|
|
6
|
+
# by whom, and whether it was answered.
|
|
7
|
+
#
|
|
8
|
+
# Read-only plus create. A request is a record of something that
|
|
9
|
+
# happened, so editing one would falsify the audit trail the record
|
|
10
|
+
# exists to provide; erasing the log of an erasure is worse still.
|
|
11
|
+
class DataRequestsController < ResourceController
|
|
12
|
+
scoped_resource :customers
|
|
13
|
+
|
|
14
|
+
def create
|
|
15
|
+
authorize! :create, Spree::DataRequest
|
|
16
|
+
|
|
17
|
+
result = Spree::DataRequests::Create.call(
|
|
18
|
+
store: current_store,
|
|
19
|
+
customer: customer,
|
|
20
|
+
kind: params[:kind],
|
|
21
|
+
requested_by: try_spree_current_user
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
return render_result_error(result) unless result.success?
|
|
25
|
+
|
|
26
|
+
render json: serialize_resource(result.value), status: :accepted
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def model_class
|
|
32
|
+
Spree::DataRequest
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def serializer_class
|
|
36
|
+
Spree.api.admin_data_request_serializer
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def scope
|
|
40
|
+
super.recent_first
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def collection_includes
|
|
44
|
+
[:customer]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
# Customers are global in Spree — they shop across a multi-store
|
|
50
|
+
# installation on one account — so there is no store association to
|
|
51
|
+
# narrow this through. `authorize!` above is what gates the caller,
|
|
52
|
+
# and the request records which store it was raised at.
|
|
53
|
+
def customer
|
|
54
|
+
@customer ||= Spree.customer_class.find_by_prefix_id!(params[:customer_id])
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class DeliveryMethodRulesController < ResourceController
|
|
6
|
+
scoped_resource :delivery_methods
|
|
7
|
+
|
|
8
|
+
# GET /api/v3/admin/delivery_method_rules/types
|
|
9
|
+
# Registered rule kinds with preference schemas for admin pickers.
|
|
10
|
+
def types
|
|
11
|
+
authorize! :create, Spree::DeliveryMethodRule
|
|
12
|
+
|
|
13
|
+
data = Spree.delivery_method_rules.map do |klass|
|
|
14
|
+
{
|
|
15
|
+
type: klass.api_type,
|
|
16
|
+
name: klass.human_name,
|
|
17
|
+
description: klass.human_description,
|
|
18
|
+
preference_schema: klass.serialized_preference_schema,
|
|
19
|
+
# Association-backed config (e.g. `product_ids`) a rule accepts
|
|
20
|
+
# beyond its preferences, so admin UIs can render the right
|
|
21
|
+
# editor without hardcoding rule types.
|
|
22
|
+
association_fields: association_fields_for(klass)
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
render json: { data: data }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def model_class
|
|
32
|
+
Spree::DeliveryMethodRule
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def serializer_class
|
|
36
|
+
Spree.api.admin_delivery_method_rule_serializer
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# `additional_permitted_attributes` entries are either bare symbols
|
|
42
|
+
# or `{ product_ids: [] }`-style hashes; both reduce to field names.
|
|
43
|
+
def association_fields_for(klass)
|
|
44
|
+
return [] unless klass.respond_to?(:additional_permitted_attributes)
|
|
45
|
+
|
|
46
|
+
klass.additional_permitted_attributes.flat_map do |attribute|
|
|
47
|
+
attribute.is_a?(Hash) ? attribute.keys : attribute
|
|
48
|
+
end.map(&:to_s)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module DeliveryMethods
|
|
6
|
+
# Eligibility rules nested under a delivery method. `type` is the
|
|
7
|
+
# wire shorthand from GET /delivery_method_rules/types.
|
|
8
|
+
class RulesController < ResourceController
|
|
9
|
+
scoped_resource :delivery_methods
|
|
10
|
+
|
|
11
|
+
def create
|
|
12
|
+
rule_class = Spree.delivery_method_rules.detect do |klass|
|
|
13
|
+
klass.api_type == params[:type].to_s
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if rule_class.nil?
|
|
17
|
+
return render_error(
|
|
18
|
+
code: ERROR_CODES[:validation_error],
|
|
19
|
+
message: Spree.t('errors.messages.invalid_delivery_method_rule'),
|
|
20
|
+
status: :unprocessable_entity
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@resource = rule_class.new(delivery_method: parent, active: active_param)
|
|
25
|
+
assign_rule_preferences(@resource)
|
|
26
|
+
assign_rule_products(@resource)
|
|
27
|
+
assign_extension_attributes(@resource)
|
|
28
|
+
authorize_resource!(@resource, :create)
|
|
29
|
+
|
|
30
|
+
if @resource.save
|
|
31
|
+
render json: serialize_resource(@resource), status: :created
|
|
32
|
+
else
|
|
33
|
+
render_validation_error(@resource.errors)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def update
|
|
38
|
+
@resource.active = active_param unless params[:active].nil?
|
|
39
|
+
assign_rule_preferences(@resource)
|
|
40
|
+
assign_rule_products(@resource)
|
|
41
|
+
assign_extension_attributes(@resource)
|
|
42
|
+
|
|
43
|
+
if @resource.save
|
|
44
|
+
render json: serialize_resource(@resource)
|
|
45
|
+
else
|
|
46
|
+
render_validation_error(@resource.errors)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
protected
|
|
51
|
+
|
|
52
|
+
def model_class
|
|
53
|
+
Spree::DeliveryMethodRule
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def serializer_class
|
|
57
|
+
Spree.api.admin_delivery_method_rule_serializer
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def scope
|
|
61
|
+
parent.delivery_method_rules
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def permitted_params
|
|
65
|
+
params.permit(*model_additional_permitted_attributes, :type, :active, preferences: {}, product_ids: [])
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def parent
|
|
71
|
+
@parent ||= current_store.delivery_methods.accessible_by(current_ability, :update).find_by_prefix_id!(params[:delivery_method_id])
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def active_param
|
|
75
|
+
params[:active].nil? ? true : params[:active].to_b
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# This controller assigns each field by hand rather than mass-assigning,
|
|
79
|
+
# so attributes an extension contributed have to be forwarded too or
|
|
80
|
+
# permitting them would have no effect.
|
|
81
|
+
def assign_extension_attributes(rule)
|
|
82
|
+
keys = model_additional_permitted_attributes.flat_map { |a| a.is_a?(Hash) ? a.keys : a }
|
|
83
|
+
return if keys.empty?
|
|
84
|
+
|
|
85
|
+
rule.assign_attributes(permitted_params.to_h.slice(*keys.map(&:to_s)))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def assign_rule_preferences(rule)
|
|
89
|
+
(permitted_params[:preferences] || {}).each do |key, value|
|
|
90
|
+
next unless rule.has_preference?(key)
|
|
91
|
+
|
|
92
|
+
rule.set_preference(key, value)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Association-backed rule config (ExcludedProductsRule). Products are
|
|
97
|
+
# looked up within the rule's store and through the caller's ability;
|
|
98
|
+
# ids that resolve to nothing are dropped rather than failing the
|
|
99
|
+
# save, since an unreachable product cannot become an exclusion. A
|
|
100
|
+
# nil param leaves the selection untouched; an empty array clears it.
|
|
101
|
+
def assign_rule_products(rule)
|
|
102
|
+
ids = permitted_params[:product_ids]
|
|
103
|
+
return if ids.nil? || !rule.respond_to?(:products)
|
|
104
|
+
|
|
105
|
+
rule.products = rule.store.products.
|
|
106
|
+
accessible_by(current_ability, :show).
|
|
107
|
+
where(id: decode_prefixed_ids(ids))
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|