spree_core 6.0.0.beta4 → 6.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/app/helpers/spree/images_helper.rb +0 -57
- data/app/jobs/spree/base_job.rb +21 -0
- data/app/jobs/spree/carts/reap_expired_job.rb +2 -2
- data/app/jobs/spree/collections/regenerate_time_based_job.rb +6 -3
- data/app/jobs/spree/orders/finalize_stale_drafts_job.rb +8 -5
- data/app/jobs/spree/payments/cancel_unused_sessions_job.rb +61 -0
- data/app/jobs/spree/search_provider/index_job.rb +4 -0
- data/app/jobs/spree/seller_payouts/sweep_seller_job.rb +2 -0
- data/app/jobs/spree/uploads/purge_unattached_job.rb +49 -0
- data/app/mailers/spree/admin_user_mailer.rb +4 -19
- data/app/mailers/spree/base_mailer.rb +97 -13
- data/app/mailers/spree/email_template_mailer.rb +27 -0
- data/app/mailers/spree/export_mailer.rb +3 -4
- data/app/mailers/spree/import_mailer.rb +3 -4
- data/app/mailers/spree/invitation_mailer.rb +24 -7
- data/app/mailers/spree/seller_user_mailer.rb +4 -16
- data/app/mailers/spree/webhook_mailer.rb +2 -2
- data/app/models/concerns/spree/acted_by.rb +1 -1
- data/app/models/concerns/spree/admin_user_methods.rb +15 -1
- data/app/models/concerns/spree/api_typed.rb +91 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +41 -13
- data/app/models/concerns/spree/calculator/currency_amounts.rb +1 -1
- data/app/models/concerns/spree/calculator/tiers.rb +63 -0
- data/app/models/concerns/spree/canonical_decimals.rb +61 -0
- data/app/models/concerns/spree/customer_methods.rb +23 -18
- data/app/models/concerns/spree/derived_number.rb +11 -13
- data/app/models/concerns/spree/email_template_identity.rb +52 -0
- data/app/models/concerns/spree/parameterizable_name.rb +2 -0
- data/app/models/concerns/spree/payment_session_transitions.rb +8 -2
- data/app/models/concerns/spree/post_sale/taxation.rb +54 -0
- data/app/models/concerns/spree/post_sale/taxed_line.rb +51 -0
- data/app/models/concerns/spree/preference_schema/json_schema.rb +139 -0
- data/app/models/concerns/spree/preference_schema.rb +62 -32
- data/app/models/concerns/spree/product_scopes.rb +16 -2
- data/app/models/concerns/spree/provider_listing.rb +41 -0
- data/app/models/concerns/spree/publishable.rb +82 -14
- data/app/models/concerns/spree/purchase/addresses.rb +23 -10
- data/app/models/concerns/spree/purchase/currency.rb +1 -1
- data/app/models/concerns/spree/purchase/deprecated_aliases.rb +87 -0
- data/app/models/concerns/spree/purchase/gift_cards.rb +10 -4
- data/app/models/concerns/spree/purchase/locale.rb +1 -1
- data/app/models/concerns/spree/purchase/payment_processing.rb +8 -4
- data/app/models/concerns/spree/purchase/purchase_order.rb +9 -4
- data/app/models/concerns/spree/purchase/store_credits.rb +36 -1
- data/app/models/concerns/spree/purchase/totals.rb +49 -8
- data/app/models/concerns/spree/ransackable_attributes.rb +46 -0
- data/app/models/concerns/spree/receivable.rb +1 -1
- data/app/models/concerns/spree/searchable.rb +0 -4
- data/app/models/concerns/spree/secret_preferences.rb +59 -0
- data/app/models/concerns/spree/signed_id_attachments.rb +54 -0
- data/app/models/concerns/spree/single_store_resource.rb +1 -1
- data/app/models/concerns/spree/stores/email_branding.rb +32 -0
- data/app/models/concerns/spree/stores/markets.rb +5 -2
- data/app/models/concerns/spree/type_labels.rb +38 -0
- data/app/models/concerns/spree/typed_adjustment_line.rb +5 -6
- data/app/models/concerns/spree/typed_associations.rb +12 -18
- data/app/models/concerns/spree/vat_price_calculation.rb +5 -6
- data/app/models/spree/address.rb +12 -2
- data/app/models/spree/adjusters/largest_remainder.rb +14 -1
- data/app/models/spree/adjusters/promotion.rb +4 -19
- data/app/models/spree/allowed_origin.rb +3 -1
- data/app/models/spree/api_key.rb +5 -6
- data/app/models/spree/authentication/strategies/oidc_strategy.rb +5 -5
- data/app/models/spree/base.rb +99 -22
- data/app/models/spree/calculator/flat_percent_item_total.rb +2 -4
- data/app/models/spree/calculator/flat_rate.rb +3 -5
- data/app/models/spree/calculator/flexi_rate.rb +4 -6
- data/app/models/spree/calculator/percent_on_line_item.rb +2 -2
- data/app/models/spree/calculator/price_sack.rb +5 -7
- data/app/models/spree/calculator/shipping/digital_delivery.rb +3 -5
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +7 -7
- data/app/models/spree/calculator/shipping/flat_rate.rb +5 -7
- data/app/models/spree/calculator/shipping/flexi_rate.rb +4 -6
- data/app/models/spree/calculator/shipping/per_item.rb +3 -5
- data/app/models/spree/calculator/shipping/price_sack.rb +5 -7
- data/app/models/spree/calculator/tiered_flat_rate.rb +7 -24
- data/app/models/spree/calculator/tiered_percent.rb +7 -25
- data/app/models/spree/cart.rb +78 -18
- data/app/models/spree/catalog.rb +1 -0
- data/app/models/spree/catalog_price.rb +0 -7
- data/app/models/spree/catalog_price_tier.rb +0 -8
- data/app/models/spree/category.rb +3 -1
- data/app/models/spree/channel/gating.rb +3 -2
- data/app/models/spree/channel.rb +6 -4
- data/app/models/spree/claim.rb +22 -1
- data/app/models/spree/claim_line_item.rb +41 -6
- data/app/models/spree/collection.rb +2 -1
- data/app/models/spree/collection_rule.rb +5 -21
- data/app/models/spree/commission_line.rb +1 -1
- data/app/models/spree/commission_rate.rb +7 -4
- data/app/models/spree/commission_rate_value.rb +1 -1
- data/app/models/spree/commission_rule.rb +4 -11
- data/app/models/spree/commission_rules/category_rule.rb +2 -5
- data/app/models/spree/commission_rules/item_total_rule.rb +2 -2
- data/app/models/spree/commission_rules/product_rule.rb +1 -1
- data/app/models/spree/commission_rules/seller_rule.rb +2 -5
- data/app/models/spree/company.rb +1 -0
- data/app/models/spree/company_invitation.rb +1 -0
- data/app/models/spree/consent_record.rb +0 -1
- data/app/models/spree/credit_card.rb +1 -1
- data/app/models/spree/current.rb +23 -0
- data/app/models/spree/custom_field.rb +2 -2
- data/app/models/spree/custom_field_definition.rb +20 -35
- data/app/models/spree/custom_fields/boolean.rb +1 -1
- data/app/models/spree/custom_fields/json.rb +1 -1
- data/app/models/spree/customer_group.rb +1 -0
- data/app/models/spree/data_feed/google.rb +0 -2
- data/app/models/spree/data_request.rb +2 -1
- data/app/models/spree/delivery_method.rb +36 -14
- data/app/models/spree/delivery_method_rule.rb +4 -11
- data/app/models/spree/delivery_method_rules/channel_rule.rb +2 -5
- data/app/models/spree/delivery_method_rules/item_total_rule.rb +2 -2
- data/app/models/spree/delivery_profile.rb +1 -0
- data/app/models/spree/delivery_rate.rb +7 -8
- data/app/models/spree/delivery_rate_provider/base.rb +1 -0
- data/app/models/spree/delivery_zone.rb +1 -2
- data/app/models/spree/delivery_zone_member.rb +4 -4
- data/app/models/spree/digital_asset.rb +7 -0
- data/app/models/spree/digital_asset_provider/base.rb +2 -0
- data/app/models/spree/digital_link.rb +2 -5
- data/app/models/spree/discount.rb +1 -1
- data/app/models/spree/email_template.rb +25 -0
- data/app/models/spree/email_template_draft.rb +13 -0
- data/app/models/spree/email_template_revision.rb +17 -0
- data/app/models/spree/email_templates/entry.rb +118 -0
- data/app/models/spree/email_templates/sample_record.rb +16 -0
- data/app/models/spree/emails/branding.rb +80 -0
- data/app/models/spree/exchange.rb +16 -1
- data/app/models/spree/exchange_line_item.rb +121 -5
- data/app/models/spree/export.rb +0 -1
- data/app/models/spree/exports/products.rb +10 -1
- data/app/models/spree/exports/report.rb +3 -3
- data/app/models/spree/fee.rb +4 -2
- data/app/models/spree/file_upload.rb +155 -0
- data/app/models/spree/fulfillment.rb +66 -30
- data/app/models/spree/fulfillment_changer.rb +2 -2
- data/app/models/spree/fulfillment_group.rb +6 -1
- data/app/models/spree/fulfillment_item.rb +0 -4
- data/app/models/spree/fulfillment_provider/base.rb +1 -0
- data/app/models/spree/gateway/bogus.rb +6 -0
- data/app/models/spree/gateway/custom_payment_source_method.rb +5 -0
- data/app/models/spree/gateway.rb +6 -2
- data/app/models/spree/gift_card.rb +18 -8
- data/app/models/spree/gift_card_batch.rb +3 -5
- data/app/models/spree/import.rb +5 -7
- data/app/models/spree/import_mapping.rb +1 -2
- data/app/models/spree/import_row.rb +2 -2
- data/app/models/spree/import_schemas/products.rb +1 -0
- data/app/models/spree/integration.rb +9 -19
- data/app/models/spree/invitation.rb +5 -5
- data/app/models/spree/line_item.rb +15 -4
- data/app/models/spree/locale.rb +11 -8
- data/app/models/spree/market.rb +8 -2
- data/app/models/spree/media.rb +1 -9
- data/app/models/spree/newsletter_subscriber.rb +4 -0
- data/app/models/spree/option_type.rb +2 -1
- data/app/models/spree/option_value.rb +2 -1
- data/app/models/spree/order.rb +60 -142
- data/app/models/spree/order_group.rb +18 -4
- data/app/models/spree/order_inventory.rb +10 -5
- data/app/models/spree/order_promotion.rb +1 -1
- data/app/models/spree/order_routing/has_strategy_preference.rb +1 -1
- data/app/models/spree/order_routing/strategy/base.rb +4 -2
- data/app/models/spree/order_routing/strategy/rules.rb +1 -1
- data/app/models/spree/order_routing_rule.rb +6 -22
- data/app/models/spree/package_type.rb +2 -2
- data/app/models/spree/payment/gateway_options.rb +15 -53
- data/app/models/spree/payment/processing.rb +2 -4
- data/app/models/spree/payment.rb +21 -13
- data/app/models/spree/payment_method/check.rb +2 -0
- data/app/models/spree/payment_method/session_instrumentation.rb +1 -0
- data/app/models/spree/payment_method/store_credit.rb +15 -13
- data/app/models/spree/payment_method.rb +78 -6
- data/app/models/spree/payment_session.rb +5 -1
- data/app/models/spree/payment_setup_session.rb +1 -0
- data/app/models/spree/payout_provider/base.rb +3 -1
- data/app/models/spree/pickup_point_provider/base.rb +2 -0
- data/app/models/spree/policy.rb +1 -0
- data/app/models/spree/price.rb +17 -14
- data/app/models/spree/price_adjustment_tier.rb +4 -0
- data/app/models/spree/price_list.rb +14 -9
- data/app/models/spree/price_rules/channel_rule.rb +3 -6
- data/app/models/spree/price_rules/customer_group_rule.rb +3 -6
- data/app/models/spree/price_rules/market_rule.rb +2 -5
- data/app/models/spree/price_rules/user_rule.rb +1 -3
- data/app/models/spree/product/channels.rb +9 -2
- data/app/models/spree/product.rb +54 -30
- data/app/models/spree/product_submission.rb +0 -12
- data/app/models/spree/product_type.rb +1 -1
- data/app/models/spree/promotion/actions/create_line_items.rb +28 -18
- data/app/models/spree/promotion/rules/category.rb +1 -5
- data/app/models/spree/promotion/rules/channel.rb +2 -9
- data/app/models/spree/promotion/rules/country.rb +3 -8
- data/app/models/spree/promotion/rules/currency.rb +1 -5
- data/app/models/spree/promotion/rules/customer_group.rb +2 -9
- data/app/models/spree/promotion/rules/first_order.rb +0 -4
- data/app/models/spree/promotion/rules/item_total.rb +6 -10
- data/app/models/spree/promotion/rules/market.rb +2 -9
- data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -4
- data/app/models/spree/promotion/rules/option_value.rb +2 -6
- data/app/models/spree/promotion/rules/product.rb +1 -5
- data/app/models/spree/promotion/rules/user.rb +0 -4
- data/app/models/spree/promotion/rules/user_logged_in.rb +0 -4
- data/app/models/spree/promotion.rb +36 -6
- data/app/models/spree/promotion_action.rb +7 -14
- data/app/models/spree/promotion_action_line_item.rb +1 -1
- data/app/models/spree/promotion_handler/coupon.rb +59 -27
- data/app/models/spree/promotion_rule.rb +7 -14
- data/app/models/spree/purchase_order.rb +3 -0
- data/app/models/spree/quantity_rule.rb +1 -1
- data/app/models/spree/refund.rb +41 -18
- data/app/models/spree/return.rb +31 -2
- data/app/models/spree/return_line_item.rb +65 -14
- data/app/models/spree/role.rb +7 -7
- data/app/models/spree/saved_report.rb +2 -1
- data/app/models/spree/search_provider/base.rb +4 -0
- data/app/models/spree/seller.rb +10 -2
- data/app/models/spree/seller_payout.rb +8 -0
- data/app/models/spree/seller_requirement.rb +5 -12
- data/app/models/spree/seller_requirement_custom_field.rb +1 -2
- data/app/models/spree/seller_requirement_submission.rb +3 -2
- data/app/models/spree/seller_requirements/accept_terms.rb +2 -3
- data/app/models/spree/seller_transfer.rb +6 -0
- data/app/models/spree/shipping_label.rb +2 -0
- data/app/models/spree/stock/availability_validator.rb +2 -2
- data/app/models/spree/stock/estimator.rb +1 -1
- data/app/models/spree/stock/inventory_unit_builder.rb +1 -1
- data/app/models/spree/stock/packer.rb +2 -2
- data/app/models/spree/stock/splitter/weight.rb +1 -1
- data/app/models/spree/stock_level/custom_events.rb +6 -0
- data/app/models/spree/stock_level.rb +3 -1
- data/app/models/spree/stock_location.rb +1 -0
- data/app/models/spree/stock_movement.rb +1 -1
- data/app/models/spree/stock_receipt_item.rb +1 -1
- data/app/models/spree/stock_reservation.rb +2 -2
- data/app/models/spree/stock_transfer.rb +6 -2
- data/app/models/spree/store.rb +70 -19
- data/app/models/spree/store_credit.rb +13 -13
- data/app/models/spree/store_credit_event.rb +5 -5
- data/app/models/spree/supplier.rb +1 -0
- data/app/models/spree/tax_category.rb +1 -0
- data/app/models/spree/tax_exemption_certificate.rb +3 -0
- data/app/models/spree/tax_identifier.rb +3 -1
- data/app/models/spree/tax_line.rb +53 -3
- data/app/models/spree/tax_provider/base.rb +71 -14
- data/app/models/spree/tax_provider/internal.rb +70 -41
- data/app/models/spree/tax_provider/recorded_share.rb +114 -0
- data/app/models/spree/tax_rate.rb +30 -8
- data/app/models/spree/taxon.rb +1 -1
- data/app/models/spree/taxonomy.rb +0 -1
- data/app/models/spree/update_status.rb +25 -0
- data/app/models/spree/variant.rb +10 -12
- data/app/models/spree/variant_media.rb +1 -1
- data/app/models/spree/webhook_delivery.rb +1 -0
- data/app/models/spree/webhook_endpoint.rb +46 -13
- data/app/models/spree/wishlist.rb +1 -6
- data/app/models/spree/wishlist_item/custom_events.rb +6 -0
- data/app/presenters/spree/csv/customer_presenter.rb +1 -1
- data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +1 -1
- data/app/presenters/spree/csv/order_line_item_presenter.rb +10 -6
- data/app/presenters/spree/csv/price_list_price_presenter.rb +3 -8
- data/app/presenters/spree/csv/product_variant_presenter.rb +59 -20
- data/app/presenters/spree/csv/purchase_order_item_presenter.rb +1 -3
- data/app/serializers/spree/emails/base_serializer.rb +14 -0
- data/app/serializers/spree/emails/export_serializer.rb +13 -0
- data/app/serializers/spree/emails/import_serializer.rb +19 -0
- data/app/serializers/spree/emails/invitation_serializer.rb +28 -0
- data/app/serializers/spree/emails/store_serializer.rb +31 -0
- data/app/serializers/spree/emails/user_serializer.rb +12 -0
- data/app/serializers/spree/emails/webhook_endpoint_serializer.rb +16 -0
- data/app/services/spree/carts/create.rb +8 -2
- data/app/services/spree/carts/destroy.rb +2 -2
- data/app/services/spree/carts/remove_out_of_stock_items.rb +2 -2
- data/app/services/spree/carts/split_by_seller.rb +1 -1
- data/app/services/spree/carts/update.rb +22 -8
- data/app/services/spree/catalogs/set_product_terms.rb +1 -1
- data/app/services/spree/categories/add_products.rb +13 -31
- data/app/services/spree/categories/remove_products.rb +12 -51
- data/app/services/spree/checkout/advance.rb +1 -4
- data/app/services/spree/collections/add_products.rb +10 -23
- data/app/services/spree/collections/remove_products.rb +7 -43
- data/app/services/spree/coupon_codes/bulk_generate.rb +8 -14
- data/app/services/spree/data_requests/create.rb +1 -1
- data/app/services/spree/deliveries/destroy.rb +2 -2
- data/app/services/spree/email_templates/check.rb +58 -0
- data/app/services/spree/email_templates/no_sample_record.rb +7 -0
- data/app/services/spree/email_templates/preview.rb +99 -0
- data/app/services/spree/emails/file_system.rb +23 -0
- data/app/services/spree/emails/filters.rb +84 -0
- data/app/services/spree/emails/liquid_context.rb +48 -0
- data/app/services/spree/emails/rendered_email.rb +14 -0
- data/app/services/spree/emails/renderer.rb +125 -0
- data/app/services/spree/emails/template.rb +51 -0
- data/app/services/spree/emails/template_data.rb +23 -0
- data/app/services/spree/emails/template_resolver.rb +109 -0
- data/app/services/spree/emails/text_converter.rb +72 -0
- data/app/services/spree/emails/translation_inliner.rb +134 -0
- data/app/services/spree/imports/row_processors/price_list_price.rb +10 -10
- data/app/services/spree/imports/row_processors/product_variant.rb +77 -34
- data/app/services/spree/imports/row_processors/purchase_order.rb +13 -13
- data/app/services/spree/locales.rb +43 -10
- data/app/services/spree/newsletter/subscribe.rb +8 -12
- data/app/services/spree/orders/build_fulfillments.rb +3 -2
- data/app/services/spree/orders/create.rb +5 -4
- data/app/services/spree/orders/discounts/create.rb +14 -11
- data/app/services/spree/orders/discounts/destroy.rb +1 -0
- data/app/services/spree/orders/discounts/update.rb +1 -0
- data/app/services/spree/orders/fees/create.rb +1 -0
- data/app/services/spree/orders/fees/destroy.rb +1 -0
- data/app/services/spree/orders/fees/update.rb +1 -0
- data/app/services/spree/orders/remove_line_item.rb +13 -3
- data/app/services/spree/orders/update.rb +10 -6
- data/app/services/spree/orders/update_item.rb +6 -3
- data/app/services/spree/orders/update_statuses.rb +3 -1
- data/app/services/spree/prices/bulk_upsert.rb +32 -25
- data/app/services/spree/product_memberships.rb +61 -0
- data/app/services/spree/returns/eligibility_validator.rb +1 -1
- data/app/services/spree/search_provider/custom_field_schema.rb +2 -2
- data/app/services/spree/seeds/commission_rates.rb +1 -1
- data/app/services/spree/seeds/digital_delivery.rb +1 -1
- data/app/services/spree/seeds/payment_methods.rb +2 -2
- data/app/services/spree/seeds/saved_reports.rb +3 -3
- data/app/services/spree/seeds/stores.rb +1 -1
- data/app/services/spree/sellers/requirements.rb +1 -2
- data/app/services/spree/shipping_labels/confirm_refund.rb +1 -1
- data/app/services/spree/shipping_labels/store_file.rb +3 -3
- data/app/services/spree/stock_levels/correct.rb +3 -3
- data/app/services/spree/stock_reservations/reserve.rb +2 -3
- data/app/services/spree/store_credits/apply.rb +15 -13
- data/app/services/spree/stores/provision_defaults.rb +23 -25
- data/app/services/spree/update_check.rb +160 -0
- data/app/services/spree/uploads/assign_stores.rb +92 -0
- data/app/subscribers/spree/seller_onboarding_subscriber.rb +1 -1
- data/app/validators/spree/attachment_content_type_validator.rb +19 -2
- data/app/validators/spree/locale_codes_validator.rb +22 -0
- data/app/views/layouts/spree/base_mailer.html.erb +2 -43
- data/app/views/layouts/spree/base_mailer.liquid +79 -0
- data/app/views/spree/admin_user_mailer/password_reset_email.liquid +14 -0
- data/app/views/spree/export_mailer/export_done.liquid +12 -0
- data/app/views/spree/import_mailer/import_done.liquid +15 -0
- data/app/views/spree/invitation_mailer/invitation_accepted.liquid +9 -0
- data/app/views/spree/invitation_mailer/invitation_email.liquid +13 -0
- data/app/views/spree/seller_user_mailer/password_reset_email.liquid +14 -0
- data/app/views/spree/shared/_mailer_button.html.erb +4 -5
- data/app/views/spree/shared/_mailer_hero.html.erb +6 -5
- data/app/views/spree/shared/_summary_row.liquid +8 -0
- data/app/views/spree/webhook_mailer/endpoint_disabled.liquid +21 -0
- data/app/workflows/spree/carts/add_item.rb +4 -4
- data/app/workflows/spree/carts/complete.rb +13 -3
- data/app/workflows/spree/carts/merge.rb +1 -1
- data/app/workflows/spree/carts/recalculate_totals.rb +5 -0
- data/app/workflows/spree/carts/upsert_items.rb +18 -9
- data/app/workflows/spree/claims/approve.rb +5 -22
- data/app/workflows/spree/claims/cancel.rb +5 -21
- data/app/workflows/spree/claims/create.rb +15 -0
- data/app/workflows/spree/claims/deny.rb +7 -0
- data/app/workflows/spree/claims/resolve.rb +34 -31
- data/app/workflows/spree/customers/anonymize.rb +3 -4
- data/app/workflows/spree/customers/create.rb +1 -1
- data/app/workflows/spree/data_requests/fulfill.rb +2 -2
- data/app/workflows/spree/deliveries/update_tracking.rb +1 -1
- data/app/workflows/spree/email_templates/discard_draft.rb +20 -0
- data/app/workflows/spree/email_templates/publish.rb +70 -0
- data/app/workflows/spree/email_templates/restore_revision.rb +33 -0
- data/app/workflows/spree/email_templates/revert.rb +29 -0
- data/app/workflows/spree/email_templates/save_draft.rb +85 -0
- data/app/workflows/spree/exchanges/approve.rb +5 -22
- data/app/workflows/spree/exchanges/cancel.rb +5 -21
- data/app/workflows/spree/exchanges/create.rb +6 -0
- data/app/workflows/spree/exchanges/fulfill.rb +75 -51
- data/app/workflows/spree/exchanges/receive.rb +6 -65
- data/app/workflows/spree/fulfillments/cancel.rb +1 -1
- data/app/workflows/spree/fulfillments/create.rb +53 -49
- data/app/workflows/spree/fulfillments/fulfill.rb +23 -27
- data/app/workflows/spree/fulfillments/mark_delivered.rb +1 -1
- data/app/workflows/spree/fulfillments/replacements.rb +59 -0
- data/app/workflows/spree/gift_cards/apply.rb +2 -2
- data/app/workflows/spree/orders/add_item.rb +5 -1
- data/app/workflows/spree/orders/cancel.rb +3 -3
- data/app/workflows/spree/orders/complete.rb +16 -8
- data/app/workflows/spree/payments/capture.rb +20 -5
- data/app/workflows/spree/payments/process.rb +5 -3
- data/app/workflows/spree/post_sale/approval.rb +35 -0
- data/app/workflows/spree/post_sale/cancellation.rb +44 -0
- data/app/workflows/spree/post_sale/receipt.rb +92 -0
- data/app/workflows/spree/price_lists/update.rb +4 -4
- data/app/workflows/spree/products/nested_attributes.rb +1 -1
- data/app/workflows/spree/purchase_orders/cancel.rb +1 -1
- data/app/workflows/spree/purchase_orders/close.rb +3 -31
- data/app/workflows/spree/purchase_orders/create.rb +3 -1
- data/app/workflows/spree/purchase_orders/mark_draft.rb +2 -2
- data/app/workflows/spree/purchase_orders/mark_ordered.rb +2 -2
- data/app/workflows/spree/purchase_orders/receive.rb +1 -1
- data/app/workflows/spree/purchase_orders/update.rb +5 -34
- data/app/workflows/spree/receivables/closing_short.rb +46 -0
- data/app/workflows/spree/receivables/draft_editing.rb +48 -0
- data/app/workflows/spree/refunds/create.rb +5 -2
- data/app/workflows/spree/refunds/order_payments.rb +14 -2
- data/app/workflows/spree/refunds/tax_credit.rb +67 -0
- data/app/workflows/spree/returns/approve.rb +5 -22
- data/app/workflows/spree/returns/cancel.rb +5 -22
- data/app/workflows/spree/returns/create.rb +8 -0
- data/app/workflows/spree/returns/receive.rb +5 -76
- data/app/workflows/spree/returns/refund.rb +31 -8
- data/app/workflows/spree/seller_requirement_submissions/create.rb +1 -2
- data/app/workflows/spree/seller_transfers/reverse.rb +28 -1
- data/app/workflows/spree/shipping_labels/purchase.rb +8 -8
- data/app/workflows/spree/shipping_labels/record.rb +7 -7
- data/app/workflows/spree/shipping_labels/refund.rb +2 -2
- data/app/workflows/spree/stock_receipts/recording.rb +4 -4
- data/app/workflows/spree/stock_transfers/cancel.rb +2 -2
- data/app/workflows/spree/stock_transfers/close.rb +3 -30
- data/app/workflows/spree/stock_transfers/create.rb +3 -1
- data/app/workflows/spree/stock_transfers/mark_draft.rb +1 -1
- data/app/workflows/spree/stock_transfers/mark_in_transit.rb +3 -3
- data/app/workflows/spree/stock_transfers/mark_ready.rb +2 -2
- data/app/workflows/spree/stock_transfers/receive.rb +1 -1
- data/app/workflows/spree/stock_transfers/update.rb +5 -33
- data/config/currency_exponents.json +180 -0
- data/config/i18n-tasks.yml +32 -18
- data/config/initializers/alba.rb +7 -0
- data/config/language_names.csv +264 -0
- data/config/locales/ar.yml +811 -0
- data/config/locales/be.yml +855 -0
- data/config/locales/bg.yml +723 -0
- data/config/locales/ca.yml +689 -0
- data/config/locales/content_locales.rb +9 -0
- data/config/locales/cs.yml +855 -0
- data/config/locales/da.yml +771 -0
- data/config/locales/de-CH.yml +248 -0
- data/config/locales/de.yml +835 -0
- data/config/locales/el.yml +769 -0
- data/config/locales/en.yml +47 -505
- data/config/locales/es-CL.yml +301 -0
- data/config/locales/es-EC.yml +186 -0
- data/config/locales/es-MX.yml +334 -0
- data/config/locales/es.yml +831 -0
- data/config/locales/et.yml +644 -0
- data/config/locales/fa.yml +709 -0
- data/config/locales/fi.yml +771 -0
- data/config/locales/fr.yml +830 -0
- data/config/locales/hu.yml +751 -0
- data/config/locales/id.yml +756 -0
- data/config/locales/it.yml +833 -0
- data/config/locales/ja.yml +726 -0
- data/config/locales/km.yml +759 -0
- data/config/locales/ko.yml +575 -0
- data/config/locales/ku.yml +753 -0
- data/config/locales/lt.yml +821 -0
- data/config/locales/lv.yml +685 -0
- data/config/locales/nb.yml +824 -0
- data/config/locales/ne.yml +823 -0
- data/config/locales/nl.yml +826 -0
- data/config/locales/pl.yml +835 -0
- data/config/locales/pt-BR.yml +547 -0
- data/config/locales/pt.yml +636 -0
- data/config/locales/ro.yml +750 -0
- data/config/locales/ru.yml +834 -0
- data/config/locales/sk.yml +680 -0
- data/config/locales/sl-SI.yml +600 -0
- data/config/locales/sv.yml +827 -0
- data/config/locales/th.yml +745 -0
- data/config/locales/tr.yml +777 -0
- data/config/locales/uk.yml +836 -0
- data/config/locales/vi.yml +768 -0
- data/config/locales/zh-CN.yml +786 -0
- data/config/locales/zh-TW.yml +834 -0
- data/db/migrate/20260925000001_add_replacement_to_spree_fulfillment_items.rb +5 -0
- data/db/migrate/20261001000001_add_post_sale_tax.rb +30 -0
- data/db/migrate/20261001000001_convert_preferences_to_json.rb +166 -0
- data/db/migrate/20261001000001_create_spree_email_templates.rb +52 -0
- data/db/migrate/20261009000001_change_money_columns_to_decimal_19_4.rb +116 -0
- data/db/migrate/20261010000001_add_store_id_to_active_storage_blobs.rb +12 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +0 -9
- data/lib/generators/spree/dummy/templates/rails/test.rb +26 -0
- data/lib/spree/checkout/default_requirements.rb +37 -13
- data/lib/spree/core/configuration.rb +19 -1
- data/lib/spree/core/controller_helpers/store.rb +1 -1
- data/lib/spree/core/dependencies.rb +5 -4
- data/lib/spree/core/emails/escaped_output.rb +60 -0
- data/lib/spree/core/engine.rb +72 -165
- data/lib/spree/core/permissions/default_catalog.rb +5 -0
- data/lib/spree/core/preferences/invalid_preferences.rb +18 -0
- data/lib/spree/core/preferences/json_conversion.rb +186 -0
- data/lib/spree/core/preferences/masking.rb +55 -2
- data/lib/spree/core/preferences/preferable.rb +343 -103
- data/lib/spree/core/preferences/preferable_class_methods.rb +188 -136
- data/lib/spree/core/previews/import_preview.rb +10 -0
- data/lib/spree/core/ransack_configuration.rb +13 -2
- data/lib/spree/core/tax/provider_error.rb +37 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +91 -373
- data/lib/spree/emails/editable_templates.rb +82 -0
- data/lib/spree/events/catalog.rb +189 -0
- data/lib/spree/events.rb +21 -1
- data/lib/spree/hooks.rb +0 -17
- data/lib/spree/i18n.rb +32 -15
- data/lib/spree/iso_data.rb +7 -0
- data/lib/spree/localized_number.rb +6 -0
- data/lib/spree/migrations.rb +4 -1
- data/lib/spree/money.rb +196 -15
- data/lib/spree/reporting/adapters/base.rb +7 -6
- data/lib/spree/reporting/adapters/live.rb +6 -6
- data/lib/spree/reporting/default_vocabulary.rb +22 -10
- data/lib/spree/reporting/hydration.rb +1 -1
- data/lib/spree/reporting/query.rb +8 -0
- data/lib/spree/reporting/registry.rb +13 -0
- data/lib/spree/reporting/schema.rb +10 -10
- data/lib/spree/testing_support/editable_email_templates.rb +61 -0
- data/lib/spree/testing_support/emails.rb +22 -0
- data/lib/spree/testing_support/factories/cart_factory.rb +1 -1
- data/lib/spree/testing_support/factories/email_template_factory.rb +28 -0
- data/lib/spree/testing_support/factories/order_factory.rb +2 -2
- data/lib/spree/testing_support/factories/product_factory.rb +9 -0
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -1
- data/lib/spree/testing_support/i18n.rb +3 -94
- data/lib/spree/testing_support/lifecycle_events.rb +1 -1
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/lib/spree/testing_support/preferences.rb +0 -5
- data/lib/spree/testing_support/store.rb +9 -1
- data/lib/spree/upgrades/5_6_to_6_0/manifest.yml +67 -1
- data/lib/spree/uploads.rb +101 -0
- data/lib/tasks/categories_and_collections.rake +3 -3
- data/lib/tasks/core.rake +6 -4
- data/lib/tasks/markets.rake +2 -1
- data/lib/tasks/media.rake +3 -3
- data/lib/tasks/migrate_users_to_customers.rake +23 -18
- data/lib/tasks/money.rake +46 -0
- data/lib/tasks/package_types.rake +1 -1
- data/lib/tasks/preferences_json.rake +101 -0
- data/lib/tasks/seller_sample_data.rake +2 -2
- data/lib/tasks/store_settings.rake +13 -6
- data/lib/tasks/typed_adjustments_migration.rake +1 -1
- data/lib/tasks/uploads.rake +19 -0
- data/spec/fixtures/mailer_views/custom_views_probe_mailer/welcome_email.html.erb +4 -0
- metadata +219 -46
- data/app/jobs/spree/products/touch_categories_job.rb +0 -15
- data/app/jobs/spree/products/touch_taxons_job.rb +0 -13
- data/app/models/acts_as_taggable_on/tag_decorator.rb +0 -10
- data/app/models/concerns/spree/has_image_alt_text.rb +0 -18
- data/app/models/spree/base_analytics_event_handler.rb +0 -54
- data/app/models/spree/invitations/store.rb +0 -6
- data/app/models/spree/preference.rb +0 -14
- data/app/models/spree/promotion_handler/page.rb +0 -25
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +0 -60
- data/app/models/spree/stock/differentiator.rb +0 -45
- data/app/presenters/spree/filters/options_presenter.rb +0 -47
- data/app/services/spree/carts/empty.rb +0 -42
- data/app/services/spree/country_to_timezone.rb +0 -273
- data/app/services/spree/payments/create.rb +0 -92
- data/app/validators/spree/url_validator.rb +0 -23
- data/app/views/active_storage/blobs/_blob.html.erb +0 -14
- data/app/views/spree/admin_user_mailer/password_reset_email.html.erb +0 -8
- data/app/views/spree/export_mailer/export_done.html.erb +0 -7
- data/app/views/spree/import_mailer/import_done.html.erb +0 -12
- data/app/views/spree/invitation_mailer/invitation_accepted.html.erb +0 -4
- data/app/views/spree/invitation_mailer/invitation_email.html.erb +0 -12
- data/app/views/spree/seller_user_mailer/password_reset_email.html.erb +0 -8
- data/app/views/spree/shared/_base_mailer_footer.html.erb +0 -19
- data/app/views/spree/shared/_base_mailer_header.html.erb +0 -8
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +0 -399
- data/app/views/spree/shared/_mailer_logo.html.erb +0 -41
- data/app/views/spree/shared/_purchased_items_styles.html.erb +0 -119
- data/app/views/spree/webhook_mailer/endpoint_disabled.html.erb +0 -51
- data/app/views/spree/webhook_mailer/endpoint_disabled.text.erb +0 -10
- data/app/workflows/spree/fulfillments/purchase_label.rb +0 -40
- data/app/workflows/spree/returns/purchase_label.rb +0 -32
- data/lib/spree/analytics.rb +0 -11
- data/lib/spree/core/preferences/scoped_store.rb +0 -34
- data/lib/spree/core/preferences/store.rb +0 -105
- data/lib/spree/translation_migrations.rb +0 -52
|
@@ -1,169 +1,221 @@
|
|
|
1
1
|
module Spree::Preferences
|
|
2
2
|
module PreferableClassMethods
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
# Bumped by every declaration anywhere, so a class's cached view of its
|
|
4
|
+
# preferences is rebuilt when an ancestor gains one after the class was
|
|
5
|
+
# loaded — a decorator adding a secret to Spree::PaymentMethod, say.
|
|
6
|
+
@declarations = 0
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
attr_accessor :declarations
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Every preference the class declares, inherited ones included, in
|
|
13
|
+
# declaration order — so an admin form can present them the way their
|
|
14
|
+
# author grouped them.
|
|
15
|
+
#
|
|
16
|
+
# @return [Hash{Symbol => Hash}] name => `{ type:, default:, deprecated:, internal:, choices:, nullable:, parse_on_set: }`
|
|
17
|
+
def preference_definitions
|
|
18
|
+
preference_declarations_cache[:definitions] ||= begin
|
|
19
|
+
inherited = superclass.respond_to?(:preference_definitions) ? superclass.preference_definitions : {}
|
|
20
|
+
inherited.merge(own_preference_definitions).freeze
|
|
11
21
|
end
|
|
12
22
|
end
|
|
13
23
|
|
|
24
|
+
# Each declared preference's type, known from the declarations alone —
|
|
25
|
+
# without building a record.
|
|
26
|
+
#
|
|
27
|
+
# @return [Hash{Symbol => Symbol}]
|
|
28
|
+
def declared_preference_types
|
|
29
|
+
preference_declarations_cache[:types] ||= preference_definitions.transform_values { |definition| definition[:type] }.freeze
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Names of the `:password` preferences, which a model including
|
|
33
|
+
# {Spree::SecretPreferences} stores encrypted in `secret_preferences`.
|
|
34
|
+
#
|
|
35
|
+
# @return [Array<Symbol>]
|
|
36
|
+
def secret_preference_names
|
|
37
|
+
preference_declarations_cache[:secrets] ||= declared_preference_types.filter_map { |name, type| name if type == :password }.freeze
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# The value types a list item, a hash value or an object property may
|
|
41
|
+
# declare — what {Spree::PreferenceSchema::JsonSchema} compiles to JSON
|
|
42
|
+
# Schema, along with its `FORMATS`.
|
|
43
|
+
ITEM_TYPES = %i[string integer decimal money boolean id object].freeze
|
|
44
|
+
|
|
45
|
+
# Declares a typed preference with a `preferred_<name>` reader and writer
|
|
46
|
+
# and a `prefers_<name>?` query. On a model, the value lives in the
|
|
47
|
+
# `preferences` column (`secret_preferences` for a `:password` one) as a
|
|
48
|
+
# Rails store accessor, which brings the change methods with it:
|
|
49
|
+
# `preferred_<name>_changed?`, `_change`, `_was`,
|
|
50
|
+
# `saved_change_to_preferred_<name>?` and `preferred_<name>_before_last_save`.
|
|
51
|
+
#
|
|
52
|
+
# The declaration is the preference's contract on the wire, so it states
|
|
53
|
+
# the full type:
|
|
54
|
+
#
|
|
55
|
+
# preference :amount_min, :money
|
|
56
|
+
# preference :channel_ids, :array, of: :id, model: 'Spree::Channel', scope: ->(rule) { rule.store.channels }
|
|
57
|
+
# preference :country_codes, :array, of: :string, format: :iso_country
|
|
58
|
+
# preference :match_policy, :string, choices: %w[any all none]
|
|
59
|
+
# preference :amounts, :hash, keys: :currency, values: :money
|
|
60
|
+
# preference :tiers, :array, of: :object, properties: { threshold: :money, value: :decimal }
|
|
61
|
+
#
|
|
62
|
+
# @param name [Symbol]
|
|
63
|
+
# @param type [Symbol] `:string`, `:text`, `:boolean`, `:integer`, `:decimal`, `:money`,
|
|
64
|
+
# `:array`, `:hash`, `:password`, `:date` or `:datetime`
|
|
65
|
+
# @option options [Symbol] :of the type of each item of an `:array`
|
|
66
|
+
# @option options [Symbol] :keys the type of a `:hash`'s keys (`:string` or `:currency`)
|
|
67
|
+
# @option options [Symbol] :values the type of a `:hash`'s values
|
|
68
|
+
# @option options [Hash{Symbol => Symbol}] :properties the fields of each `of: :object` item
|
|
69
|
+
# @option options [Symbol] :format a string's domain format (see {Spree::PreferenceSchema::JsonSchema::FORMATS})
|
|
70
|
+
# @option options [String, Proc] :model the record class an `of: :id` list points at
|
|
71
|
+
# @option options [Proc] :scope `->(owner) { relation }` the ids must be found in
|
|
72
|
+
# @option options [Array, Proc] :choices the fixed set a value must come from
|
|
73
|
+
# @option options [Symbol] :currency where a `:money` preference's currency comes
|
|
74
|
+
# from: another preference or a method of the record. Defaults to the
|
|
75
|
+
# record's `currency` preference; with neither, the amount is in any currency.
|
|
14
76
|
def preference(name, type, *args)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
deprecated = options[:deprecated]
|
|
21
|
-
internal = options[:internal]
|
|
22
|
-
# The fixed set a value must come from. Turns a text box into a picker
|
|
23
|
-
# in every admin form, and is what the inclusion validation would have
|
|
24
|
-
# told the operator only after a failed save.
|
|
25
|
-
choices = options[:in]
|
|
26
|
-
nullable = options[:nullable]
|
|
27
|
-
parse_on_set = options[:parse_on_set]
|
|
28
|
-
|
|
29
|
-
# cache_key will be nil for new objects, then if we check if there
|
|
30
|
-
# is a pending preference before going to default
|
|
31
|
-
define_method preference_getter_method(name) do
|
|
32
|
-
# Rows persisted before the model gained preferences can load with a
|
|
33
|
-
# NULL column — treat that as "no stored preferences".
|
|
34
|
-
(preferences || {}).fetch(name) do
|
|
35
|
-
default.call
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
define_method preference_setter_method(name) do |value|
|
|
40
|
-
if parse_on_set.is_a?(Proc)
|
|
41
|
-
# Procs that accept more than one arg opt into receiving the
|
|
42
|
-
# owning record so they can scope (e.g. `normalize_id_preference`
|
|
43
|
-
# rejecting cross-store IDs). `arity.abs > 1` covers both the
|
|
44
|
-
# `(value, owner)` and `(value, owner = nil)` shapes.
|
|
45
|
-
value = parse_on_set.arity.abs > 1 ? parse_on_set.call(value, self) : parse_on_set.call(value)
|
|
46
|
-
end
|
|
47
|
-
value = convert_preference_value(value, type, nullable: nullable)
|
|
48
|
-
self.preferences = {} if preferences.nil?
|
|
49
|
-
preferences[name] = value
|
|
50
|
-
|
|
51
|
-
Spree::Deprecation.warn("`#{name}` is deprecated. #{deprecated}") if deprecated
|
|
52
|
-
|
|
53
|
-
# If this is an activerecord object, we need to inform
|
|
54
|
-
# ActiveRecord::Dirty that this value has changed, since this is an
|
|
55
|
-
# in-place update to the preferences hash.
|
|
56
|
-
preferences_will_change! if respond_to?(:preferences_will_change!)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
define_method preference_default_getter_method(name), &default
|
|
60
|
-
|
|
61
|
-
define_method preference_type_getter_method(name) do
|
|
62
|
-
type
|
|
77
|
+
name = name.to_sym
|
|
78
|
+
secret = type == :password
|
|
79
|
+
if secret && !include?(Spree::SecretPreferences)
|
|
80
|
+
raise ArgumentError, "#{self.name} declares the secret preference `#{name}` but cannot encrypt it. " \
|
|
81
|
+
'Include Spree::SecretPreferences and add a `secret_preferences` text column to its table.'
|
|
63
82
|
end
|
|
64
83
|
|
|
65
|
-
|
|
66
|
-
|
|
84
|
+
options = args.extract_options!
|
|
85
|
+
options.assert_valid_keys(:default, :deprecated, :in, :choices, :internal, :nullable, :parse_on_set,
|
|
86
|
+
:of, :keys, :values, :properties, :format, :model, :scope, :currency)
|
|
87
|
+
if options.key?(:in)
|
|
88
|
+
Spree::Deprecation.warn("`preference :#{name}, in:` is deprecated. Use `choices:` instead.")
|
|
89
|
+
options[:choices] ||= options.delete(:in)
|
|
67
90
|
end
|
|
91
|
+
check_preference_declaration(name, type, options)
|
|
68
92
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
93
|
+
default = options[:default]
|
|
94
|
+
dynamic_default = default.is_a?(Proc)
|
|
95
|
+
default = -> { options[:default] } unless dynamic_default
|
|
96
|
+
own_preference_definitions[name] = {
|
|
97
|
+
type: type,
|
|
98
|
+
default: default,
|
|
99
|
+
# Computed when read (the default store's currency, say), so it
|
|
100
|
+
# differs between stores and is not part of the preference's schema.
|
|
101
|
+
dynamic_default: dynamic_default,
|
|
102
|
+
deprecated: options[:deprecated],
|
|
103
|
+
# Whether the system writes the value rather than the operator — a
|
|
104
|
+
# value a provider hands back, kept out of every admin form.
|
|
105
|
+
internal: options[:internal],
|
|
106
|
+
# The fixed set a value must come from; turns a text box into a picker.
|
|
107
|
+
choices: options[:choices],
|
|
108
|
+
nullable: options[:nullable],
|
|
109
|
+
parse_on_set: options[:parse_on_set],
|
|
110
|
+
of: options[:of],
|
|
111
|
+
keys: options[:keys],
|
|
112
|
+
values: options[:values],
|
|
113
|
+
properties: options[:properties],
|
|
114
|
+
format: options[:format],
|
|
115
|
+
model: options[:model],
|
|
116
|
+
scope: options[:scope],
|
|
117
|
+
currency: options[:currency]
|
|
118
|
+
}
|
|
119
|
+
PreferableClassMethods.declarations += 1
|
|
120
|
+
|
|
121
|
+
store_accessor(secret ? :secret_preferences : :preferences, name, prefix: :preferred)
|
|
122
|
+
|
|
123
|
+
# Overrides the store accessor's reader and writer, which treat a missing
|
|
124
|
+
# key as nil; here a missing key means the declared default.
|
|
125
|
+
define_method(:"preferred_#{name}") do
|
|
126
|
+
Spree::Preferences::Preferable.restore_value(stored_preference(name) { stored_default(name) }, type)
|
|
74
127
|
end
|
|
75
128
|
|
|
76
|
-
define_method
|
|
77
|
-
|
|
129
|
+
define_method(:"preferred_#{name}=") do |value|
|
|
130
|
+
write_preference(name, cast_preference(name, value))
|
|
78
131
|
end
|
|
79
132
|
|
|
80
|
-
define_method
|
|
81
|
-
|
|
133
|
+
define_method(:"prefers_#{name}?") do
|
|
134
|
+
stored_preference(name) { raise KeyError, "key not found: #{name.inspect}" }.to_b
|
|
82
135
|
end
|
|
136
|
+
end
|
|
83
137
|
|
|
84
|
-
|
|
85
|
-
|
|
138
|
+
# Gives each named preference a plain reader, writer and predicate, so the
|
|
139
|
+
# API reads and writes `guest_checkout` rather than the DSL's
|
|
140
|
+
# `preferred_guest_checkout` — the methods Rails' `has_delegated_json`
|
|
141
|
+
# defines, so callers would not change if the storage ever moved to it.
|
|
142
|
+
# Grants no write access: each API controller still lists what it permits.
|
|
143
|
+
#
|
|
144
|
+
# exposes_preferences :guest_checkout, :timezone
|
|
145
|
+
#
|
|
146
|
+
# @param names [Array<Symbol>]
|
|
147
|
+
# @return [void]
|
|
148
|
+
def exposes_preferences(*names)
|
|
149
|
+
names.each do |name|
|
|
150
|
+
name = name.to_sym
|
|
151
|
+
raise ArgumentError, "#{self.name} has no preference `#{name}` to expose" unless preference_definitions.key?(name)
|
|
152
|
+
raise ArgumentError, "#{self.name} cannot expose the preference `#{name}`: a method of that name exists" if method_defined?(name)
|
|
153
|
+
|
|
154
|
+
define_method(name) { public_send(:"preferred_#{name}") }
|
|
155
|
+
define_method(:"#{name}=") { |value| public_send(:"preferred_#{name}=", value) }
|
|
156
|
+
# As `has_json` defines one; a predicate the model already has (one
|
|
157
|
+
# that falls back to another setting, say) is kept.
|
|
158
|
+
define_method(:"#{name}?") { public_send(:"preferred_#{name}").present? } unless method_defined?(:"#{name}?")
|
|
86
159
|
end
|
|
160
|
+
self.exposed_preference_names = (exposed_preference_names | names.map(&:to_sym)).freeze
|
|
161
|
+
end
|
|
87
162
|
|
|
88
|
-
|
|
89
|
-
|
|
163
|
+
# The plain name an exposed preference goes by, for a key still using the
|
|
164
|
+
# DSL's `preferred_` prefix — an error key or a 5.x request parameter.
|
|
165
|
+
#
|
|
166
|
+
# @param key [Symbol, String] e.g. `preferred_guest_checkout`
|
|
167
|
+
# @return [Symbol, nil] e.g. `:guest_checkout`, or nil when the key names no exposed preference
|
|
168
|
+
def exposed_preference_name(key)
|
|
169
|
+
name = key.to_s.delete_prefix('preferred_')
|
|
170
|
+
name.to_sym if name != key.to_s && exposed_preference_names.include?(name.to_sym)
|
|
171
|
+
end
|
|
90
172
|
|
|
91
|
-
|
|
92
|
-
end
|
|
173
|
+
private
|
|
93
174
|
|
|
94
|
-
|
|
95
|
-
|
|
175
|
+
# A declaration is the preference's contract on the wire. One Spree ships
|
|
176
|
+
# is always complete (a spec enforces it); an incomplete one from an
|
|
177
|
+
# extension still works in 6.0, with a schema that accepts any value.
|
|
178
|
+
def check_preference_declaration(name, type, options)
|
|
179
|
+
if options[:of] && type != :array
|
|
180
|
+
raise ArgumentError, "`of:` applies to an :array preference, not `#{name}` (#{type})"
|
|
96
181
|
end
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
preference_change(name, previous_changes) if respond_to?(:previous_changes)
|
|
182
|
+
if (options[:keys] || options[:values]) && type != :hash
|
|
183
|
+
raise ArgumentError, "`keys:` and `values:` apply to a :hash preference, not `#{name}` (#{type})"
|
|
100
184
|
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return unless respond_to?(:previous_changes)
|
|
104
|
-
|
|
105
|
-
preference_change(name, previous_changes)&.first
|
|
185
|
+
[options[:of], options[:values], *options[:properties]&.values].compact.each do |item_type|
|
|
186
|
+
raise ArgumentError, "Unknown item type `#{item_type}` on preference `#{name}`" unless ITEM_TYPES.include?(item_type)
|
|
106
187
|
end
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
respond_to?(:previous_changes) && preference_change(name, previous_changes).present?
|
|
188
|
+
if options[:format] && !Spree::PreferenceSchema::JsonSchema::FORMATS.key?(options[:format])
|
|
189
|
+
raise ArgumentError, "Unknown format `#{options[:format]}` on preference `#{name}`"
|
|
110
190
|
end
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"preferred_#{name}".to_sym
|
|
115
|
-
end
|
|
191
|
+
raise ArgumentError, "`of: :id` needs `model:` on preference `#{name}`" if options[:of] == :id && options[:model].blank?
|
|
192
|
+
raise ArgumentError, "`currency:` applies to a :money preference, not `#{name}` (#{type})" if options[:currency] && type != :money
|
|
193
|
+
raise ArgumentError, "`of: :object` needs `properties:` on preference `#{name}`" if options[:of] == :object && options[:properties].blank?
|
|
116
194
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def preference_deprecated_getter_method(name)
|
|
126
|
-
"preferred_#{name}_deprecated".to_sym
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def preference_internal_getter_method(name)
|
|
130
|
-
"preferred_#{name}_internal".to_sym
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def preference_choices_getter_method(name)
|
|
134
|
-
"preferred_#{name}_choices".to_sym
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def preference_type_getter_method(name)
|
|
138
|
-
"preferred_#{name}_type".to_sym
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def prefers_query_method(name)
|
|
142
|
-
"prefers_#{name}?".to_sym
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def preference_change_method(name)
|
|
146
|
-
"preferred_#{name}_change".to_sym
|
|
147
|
-
end
|
|
195
|
+
missing = case type
|
|
196
|
+
when :any then 'a type other than :any'
|
|
197
|
+
when :array then '`of:`' unless options[:of]
|
|
198
|
+
when :hash then '`keys:` and `values:`' unless options[:keys] && options[:values]
|
|
199
|
+
end
|
|
200
|
+
return unless missing
|
|
148
201
|
|
|
149
|
-
|
|
150
|
-
|
|
202
|
+
Spree::Deprecation.warn(
|
|
203
|
+
"#{self.name} preference `#{name}` (#{type}) needs #{missing}; until it has one, its schema accepts any value. " \
|
|
204
|
+
'Spree 6.1 will raise for an incomplete declaration.'
|
|
205
|
+
)
|
|
151
206
|
end
|
|
152
207
|
|
|
153
|
-
def
|
|
154
|
-
|
|
208
|
+
def own_preference_definitions
|
|
209
|
+
@own_preference_definitions ||= {}
|
|
155
210
|
end
|
|
156
211
|
|
|
157
|
-
def
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def preference_previous_changed_method(name)
|
|
166
|
-
"preferred_#{name}_previously_changed?".to_sym
|
|
212
|
+
def preference_declarations_cache
|
|
213
|
+
generation = PreferableClassMethods.declarations
|
|
214
|
+
unless @preference_declarations_generation == generation
|
|
215
|
+
@preference_declarations_generation = generation
|
|
216
|
+
@preference_declarations_cache = {}
|
|
217
|
+
end
|
|
218
|
+
@preference_declarations_cache
|
|
167
219
|
end
|
|
168
220
|
end
|
|
169
221
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require_relative 'preview_data'
|
|
2
|
+
|
|
3
|
+
# Preview Spree import emails at /rails/mailers/spree/import
|
|
4
|
+
class Spree::ImportPreview < ActionMailer::Preview
|
|
5
|
+
include Spree::PreviewData::LocaleParam
|
|
6
|
+
|
|
7
|
+
def import_done
|
|
8
|
+
Spree::ImportMailer.import_done(Spree::Import.where.not(user_id: nil).last)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -6,7 +6,7 @@ module Spree
|
|
|
6
6
|
#
|
|
7
7
|
# @example Adding custom searchable fields
|
|
8
8
|
# Spree.ransack.add_attribute(Spree::Product, :seller_id)
|
|
9
|
-
# Spree.ransack.add_scope(Spree::Product, :by_seller)
|
|
9
|
+
# Spree.ransack.add_scope(Spree::Product, :by_seller, type: 'id')
|
|
10
10
|
# Spree.ransack.add_association(Spree::Product, :seller)
|
|
11
11
|
#
|
|
12
12
|
class RansackConfiguration
|
|
@@ -14,6 +14,7 @@ module Spree
|
|
|
14
14
|
@custom_attributes = Hash.new { |h, k| h[k] = [] }
|
|
15
15
|
@custom_associations = Hash.new { |h, k| h[k] = [] }
|
|
16
16
|
@custom_scopes = Hash.new { |h, k| h[k] = [] }
|
|
17
|
+
@custom_scope_types = Hash.new { |h, k| h[k] = {} }
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
# Add a custom ransackable attribute to a model.
|
|
@@ -38,8 +39,11 @@ module Spree
|
|
|
38
39
|
#
|
|
39
40
|
# @param model [Class] the model class to configure (e.g., Spree::Product)
|
|
40
41
|
# @param scope [String, Symbol] the scope to add
|
|
42
|
+
# @param type [String, Array<String>, Hash, nil] the arguments it takes, as
|
|
43
|
+
# in `ransackable_scope_types` — `'boolean'` for a scope taking none
|
|
41
44
|
# @return [Array<String>] the updated list of custom scopes
|
|
42
|
-
def add_scope(model, scope)
|
|
45
|
+
def add_scope(model, scope, type: nil)
|
|
46
|
+
@custom_scope_types[model.name.to_sym][scope.to_s] = type unless type.nil?
|
|
43
47
|
@custom_scopes[model.name.to_sym] |= [scope.to_s]
|
|
44
48
|
end
|
|
45
49
|
|
|
@@ -67,6 +71,12 @@ module Spree
|
|
|
67
71
|
@custom_scopes[model.name.to_sym]
|
|
68
72
|
end
|
|
69
73
|
|
|
74
|
+
# @param model [Class] the model class to query
|
|
75
|
+
# @return [Hash{String => Object}] argument types declared with {#add_scope}
|
|
76
|
+
def custom_scope_types_for(model)
|
|
77
|
+
@custom_scope_types[model.name.to_sym]
|
|
78
|
+
end
|
|
79
|
+
|
|
70
80
|
# Reset all custom configurations. Useful for testing.
|
|
71
81
|
#
|
|
72
82
|
# @return [void]
|
|
@@ -74,6 +84,7 @@ module Spree
|
|
|
74
84
|
@custom_attributes.clear
|
|
75
85
|
@custom_associations.clear
|
|
76
86
|
@custom_scopes.clear
|
|
87
|
+
@custom_scope_types.clear
|
|
77
88
|
end
|
|
78
89
|
end
|
|
79
90
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Tax
|
|
3
|
+
# A tax engine did not produce tax for a sale. Providers raise one of the
|
|
4
|
+
# two subclasses below; core rescues this and refuses the sale rather than
|
|
5
|
+
# completing one whose tax nobody computed — charging nothing because nobody
|
|
6
|
+
# could be asked is the error a merchant discovers in a filing.
|
|
7
|
+
#
|
|
8
|
+
# Split because a customer can only act on one of them. Retrying an outage
|
|
9
|
+
# may work; retrying a postcode the engine rejects never will, and telling
|
|
10
|
+
# someone to try again is worse than telling them nothing.
|
|
11
|
+
#
|
|
12
|
+
# The parallel is {Spree::Pricing::PriceResolution::ProviderUnavailable},
|
|
13
|
+
# which refuses a sale whose prices could not be confirmed. Neither is for a
|
|
14
|
+
# provider a merchant switched off: that is configuration, not failure, and
|
|
15
|
+
# an unconfigured engine simply has no opinion and writes no rows.
|
|
16
|
+
class ProviderError < StandardError
|
|
17
|
+
# @return [String, nil] which engine failed, for the report
|
|
18
|
+
attr_reader :provider_key
|
|
19
|
+
|
|
20
|
+
def initialize(message = nil, provider_key: nil)
|
|
21
|
+
@provider_key = provider_key
|
|
22
|
+
super(message)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# The engine could not be asked — unreachable, timed out, or answering with
|
|
27
|
+
# a fault of its own. Nothing is known about the tax, and trying again
|
|
28
|
+
# later may well succeed, so the customer is told to retry.
|
|
29
|
+
class ProviderUnavailable < ProviderError; end
|
|
30
|
+
|
|
31
|
+
# The engine was asked and said no: an address it will not accept, a
|
|
32
|
+
# misconfigured company code, a request it rejects. The service is working,
|
|
33
|
+
# so retrying changes nothing — what the engine said is the useful part and
|
|
34
|
+
# core passes its message on rather than inventing one.
|
|
35
|
+
class CalculationRefused < ProviderError; end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/spree/core/version.rb
CHANGED