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
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Core
|
|
3
|
+
module Emails
|
|
4
|
+
# HTML-escapes what a Liquid email template prints, unless the value was
|
|
5
|
+
# marked `| raw`. Applied where output is written rather than through
|
|
6
|
+
# Liquid's global filter, which `{% assign %}` also runs through — that
|
|
7
|
+
# would escape a value once when assigned and again when printed, and
|
|
8
|
+
# turn assigned numbers and lists into strings.
|
|
9
|
+
#
|
|
10
|
+
# Switched on by the `escape_output` register, which Liquid hands down to
|
|
11
|
+
# every partial, so any other Liquid the host app runs is untouched.
|
|
12
|
+
module EscapedOutput
|
|
13
|
+
def self.active?(context)
|
|
14
|
+
context.registers[:escape_output]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# `{{ value }}` and `{% echo value %}`. Variables are not tags, so this
|
|
18
|
+
# is the one place Liquid itself has to be extended.
|
|
19
|
+
module Variable
|
|
20
|
+
def render_to_output_buffer(context, output)
|
|
21
|
+
return super unless EscapedOutput.active?(context)
|
|
22
|
+
|
|
23
|
+
write_escaped(render(context), output)
|
|
24
|
+
output
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def write_escaped(value, output)
|
|
30
|
+
case value
|
|
31
|
+
when nil then nil
|
|
32
|
+
when Array then value.each { |item| write_escaped(item, output) }
|
|
33
|
+
else output << ERB::Util.html_escape(Liquid::Utils.to_s(value))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# A captured block was escaped as it rendered, so it is kept as safe
|
|
39
|
+
# HTML rather than escaped a second time when printed.
|
|
40
|
+
class Capture < Liquid::Capture
|
|
41
|
+
def render(context)
|
|
42
|
+
output = super
|
|
43
|
+
EscapedOutput.active?(context) ? output.html_safe : output
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# `{% cycle %}` writes its values straight to the output.
|
|
48
|
+
class Cycle < Liquid::Cycle
|
|
49
|
+
def render_to_output_buffer(context, output)
|
|
50
|
+
return super unless EscapedOutput.active?(context)
|
|
51
|
+
|
|
52
|
+
output << ERB::Util.html_escape(super(context, +''))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
Liquid::Variable.prepend(Spree::Core::Emails::EscapedOutput::Variable)
|
data/lib/spree/core/engine.rb
CHANGED
|
@@ -19,6 +19,7 @@ module Spree
|
|
|
19
19
|
:payout_providers,
|
|
20
20
|
:password_validator,
|
|
21
21
|
:fulfillment_providers,
|
|
22
|
+
:pickup_point_providers,
|
|
22
23
|
:tracking_carriers,
|
|
23
24
|
:stock_splitters,
|
|
24
25
|
:commission_rules,
|
|
@@ -37,19 +38,11 @@ module Spree
|
|
|
37
38
|
:taxon_rules,
|
|
38
39
|
:collection_rules,
|
|
39
40
|
:time_based_collection_rules,
|
|
40
|
-
:themes,
|
|
41
|
-
:theme_layout_sections,
|
|
42
|
-
:pages,
|
|
43
|
-
:page_sections,
|
|
44
|
-
:page_blocks,
|
|
45
|
-
:reports,
|
|
46
41
|
:translatable_resources,
|
|
47
42
|
:taggable_types,
|
|
48
43
|
:actor_classes,
|
|
49
44
|
:custom_fields,
|
|
50
45
|
:reporting,
|
|
51
|
-
:analytics_events,
|
|
52
|
-
:analytics_event_handlers,
|
|
53
46
|
:integrations,
|
|
54
47
|
:number_generators,
|
|
55
48
|
:subscribers,
|
|
@@ -60,16 +53,10 @@ module Spree
|
|
|
60
53
|
PromoEnvironment = Struct.new(:rules, :actions)
|
|
61
54
|
PricingEnvironment = Struct.new(:rules)
|
|
62
55
|
OrderRoutingEnvironment = Struct.new(:strategies, :rules)
|
|
63
|
-
# Spree::Validators, not a Struct: the sets carry register/unregister so
|
|
64
|
-
# a host can drop a core rule (see Spree.validators.addresses).
|
|
65
|
-
SpreeValidators = Spree::Validators
|
|
66
56
|
CustomFieldsEnvironment = Struct.new(:types, :enabled_resources)
|
|
67
57
|
isolate_namespace Spree
|
|
68
58
|
engine_name 'spree'
|
|
69
59
|
|
|
70
|
-
# Add app/subscribers to autoload paths
|
|
71
|
-
config.paths.add 'app/subscribers', eager_load: true
|
|
72
|
-
|
|
73
60
|
# Register bundled ActionMailer previews so they show up at /rails/mailers
|
|
74
61
|
# without the host app having to copy any files.
|
|
75
62
|
initializer 'spree.mailer_previews' do |app|
|
|
@@ -79,14 +66,28 @@ module Spree
|
|
|
79
66
|
end
|
|
80
67
|
|
|
81
68
|
initializer 'spree.environment', before: :load_config_initializers do |app|
|
|
82
|
-
|
|
69
|
+
# Spree::Validators, not a Struct: the sets carry register/unregister so
|
|
70
|
+
# a host can drop a core rule (see Spree.validators.addresses).
|
|
71
|
+
app.config.spree = Environment.new(SpreeCalculators.new, Spree::Validators.new, Spree::Core::Configuration.new, Spree::Core::Dependencies.new)
|
|
72
|
+
|
|
73
|
+
# Registries are seeded before application initializers so extensions
|
|
74
|
+
# and host apps can append their own entries from initializer files.
|
|
75
|
+
# Core's defaults are concatenated in after_initialize below.
|
|
76
|
+
%i[subscribers actor_classes commission_rules delivery_method_rules seller_requirements
|
|
77
|
+
delivery_rate_providers tax_providers pricing_providers inventory_providers
|
|
78
|
+
payout_providers digital_asset_providers delivery_profile_types pickup_point_providers].each do |registry|
|
|
79
|
+
app.config.spree[registry] = []
|
|
80
|
+
end
|
|
81
|
+
app.config.spree.line_item_comparison_hooks = Set.new
|
|
82
|
+
app.config.spree.order_routing = OrderRoutingEnvironment.new([], [])
|
|
83
|
+
app.config.spree.custom_fields = CustomFieldsEnvironment.new([], [])
|
|
84
|
+
app.config.spree.promotions = PromoEnvironment.new([])
|
|
85
|
+
app.config.spree.pricing = PricingEnvironment.new([])
|
|
83
86
|
|
|
84
|
-
app.config.active_record.yaml_column_permitted_classes ||= []
|
|
85
|
-
app.config.active_record.yaml_column_permitted_classes.concat([Symbol, BigDecimal, ActiveSupport::HashWithIndifferentAccess, ActiveSupport::TimeWithZone, ActiveSupport::TimeZone, Time])
|
|
86
87
|
Spree::Config = app.config.spree.preferences
|
|
87
|
-
Spree::RuntimeConfig = app.config.spree.preferences # for compatibility
|
|
88
88
|
Spree::Dependencies = app.config.spree.dependencies
|
|
89
89
|
Spree::Deprecation = ActiveSupport::Deprecation.new('6.0', 'Spree')
|
|
90
|
+
app.deprecators[:spree] = Spree::Deprecation
|
|
90
91
|
end
|
|
91
92
|
|
|
92
93
|
# Runs after initializers so an explicitly assigned preference — which
|
|
@@ -107,19 +108,32 @@ module Spree
|
|
|
107
108
|
app.middleware.use ::I18n::Middleware
|
|
108
109
|
end
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
# Spree's translations cover only part of the English keys in most
|
|
112
|
+
# languages, so the rest fall back to English, the one complete language.
|
|
113
|
+
# `true` (Rails' generated production.rb) falls back to the app's default
|
|
114
|
+
# locale only, so English is added after it. An app that configured its
|
|
115
|
+
# own fallback chain, or turned fallbacks off, keeps its choice.
|
|
116
|
+
initializer 'spree.i18n.fallbacks', before: :load_config_initializers do |app|
|
|
117
|
+
fallbacks = app.config.i18n.fallbacks
|
|
118
|
+
if fallbacks == true
|
|
119
|
+
app.config.i18n.fallbacks = [app.config.i18n.default_locale || :en, :en].uniq
|
|
120
|
+
elsif fallbacks.is_a?(ActiveSupport::OrderedOptions) && fallbacks.empty?
|
|
121
|
+
app.config.i18n.fallbacks = [:en]
|
|
122
|
+
end
|
|
113
123
|
end
|
|
114
124
|
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
initializer 'spree.
|
|
119
|
-
app.config.
|
|
120
|
-
|
|
125
|
+
# Spree's gems ship translations for dozens of languages. An app that
|
|
126
|
+
# limits `config.i18n.available_locales` loads only those (and English),
|
|
127
|
+
# instead of parsing every file at boot and discarding the rest.
|
|
128
|
+
initializer 'spree.i18n.locale_files', before: :load_config_initializers do |app|
|
|
129
|
+
allowed = Array(app.config.i18n.available_locales).map(&:to_s)
|
|
130
|
+
next if allowed.empty?
|
|
121
131
|
|
|
122
|
-
|
|
132
|
+
# A regional file (de-CH) holds only its differences from its base (de).
|
|
133
|
+
locales = allowed | allowed.map { |locale| locale.split('-').first } | ['en']
|
|
134
|
+
%w[Spree::Core::Engine Spree::Api::Engine Spree::Emails::Engine].filter_map(&:safe_constantize).each do |engine|
|
|
135
|
+
engine.config.paths['config/locales'].glob = "{#{locales.join(',')}}.yml"
|
|
136
|
+
end
|
|
123
137
|
end
|
|
124
138
|
|
|
125
139
|
# Seeded before application initializers so a host's
|
|
@@ -128,13 +142,6 @@ module Spree
|
|
|
128
142
|
app.config.spree.number_generators = Spree::NumberGenerators::Registry.new
|
|
129
143
|
end
|
|
130
144
|
|
|
131
|
-
initializer 'spree.register.stock_splitters', before: :load_config_initializers do |app|
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
initializer 'spree.register.line_item_comparison_hooks', before: :load_config_initializers do |app|
|
|
135
|
-
app.config.spree.line_item_comparison_hooks = Set.new
|
|
136
|
-
end
|
|
137
|
-
|
|
138
145
|
# The one eligibility rule core ships: a per-market return window,
|
|
139
146
|
# bypassed by staff. Registered before application initializers so a
|
|
140
147
|
# store can unregister it in its own initializer.
|
|
@@ -143,78 +150,6 @@ module Spree
|
|
|
143
150
|
Spree.hooks.register('exchanges.create.validate', 'Spree::Returns::EligibilityValidator')
|
|
144
151
|
end
|
|
145
152
|
|
|
146
|
-
initializer 'spree.register.payment_methods', after: 'acts_as_list.insert_into_active_record' do |app|
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
initializer 'spree.register.adjustable_adjusters' do |app|
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# Seed the order routing registries early so engines and apps can append
|
|
153
|
-
# their own strategies / rule kinds from initializer files. Core's defaults
|
|
154
|
-
# are concatenated in after_initialize below.
|
|
155
|
-
initializer 'spree.register.order_routing', before: :load_config_initializers do |app|
|
|
156
|
-
app.config.spree.order_routing = OrderRoutingEnvironment.new
|
|
157
|
-
app.config.spree.order_routing.strategies = []
|
|
158
|
-
app.config.spree.order_routing.rules = []
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Seeded early for the same reason as order routing: initializer files
|
|
162
|
-
# append custom rule kinds. Core defaults concatenate in after_initialize.
|
|
163
|
-
initializer 'spree.register.commission_rules', before: :load_config_initializers do |app|
|
|
164
|
-
app.config.spree.commission_rules = []
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
initializer 'spree.register.delivery_method_rules', before: :load_config_initializers do |app|
|
|
168
|
-
app.config.spree.delivery_method_rules = []
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# Seeded early like the other kind registries: an initializer file adds
|
|
172
|
-
# a marketplace's own requirement kinds, core's concatenate after.
|
|
173
|
-
initializer 'spree.register.seller_requirements', before: :load_config_initializers do |app|
|
|
174
|
-
app.config.spree.seller_requirements = []
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
initializer 'spree.register.delivery_rate_providers', before: :load_config_initializers do |app|
|
|
178
|
-
app.config.spree.delivery_rate_providers = []
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
# Same reason again: a tax provider gem, or a host app, registers its
|
|
182
|
-
# engine from an initializer file. Core's Internal concatenates below.
|
|
183
|
-
initializer 'spree.register.tax_providers', before: :load_config_initializers do |app|
|
|
184
|
-
app.config.spree.tax_providers = []
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
# Same reason as the tax providers above: a connector gem registers its
|
|
188
|
-
# engine from an initializer file, and core's Internal concatenates below.
|
|
189
|
-
initializer 'spree.register.pricing_providers', before: :load_config_initializers do |app|
|
|
190
|
-
app.config.spree.pricing_providers = []
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
initializer 'spree.register.inventory_providers', before: :load_config_initializers do |app|
|
|
194
|
-
app.config.spree.inventory_providers = []
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
# How sellers get paid. A provider gem — the Stripe Connect one, or a
|
|
198
|
-
# marketplace's own — registers from an initializer file; core's
|
|
199
|
-
# record-only System concatenates below.
|
|
200
|
-
initializer 'spree.register.payout_providers', before: :load_config_initializers do |app|
|
|
201
|
-
app.config.spree.payout_providers = []
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
initializer 'spree.register.digital_asset_providers', before: :load_config_initializers do |app|
|
|
205
|
-
app.config.spree.digital_asset_providers = []
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
initializer 'spree.register.delivery_profile_types', before: :load_config_initializers do |app|
|
|
209
|
-
app.config.spree.delivery_profile_types = []
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
initializer 'spree.register.custom_fields' do |app|
|
|
213
|
-
app.config.spree.custom_fields = CustomFieldsEnvironment.new
|
|
214
|
-
app.config.spree.custom_fields.types = []
|
|
215
|
-
app.config.spree.custom_fields.enabled_resources = []
|
|
216
|
-
end
|
|
217
|
-
|
|
218
153
|
# Seed the reporting vocabulary before app initializers so applications
|
|
219
154
|
# and extensions can register their own metrics/dimensions in
|
|
220
155
|
# config/initializers (see docs/plans/6.0-analytics-semantic-layer.md).
|
|
@@ -223,29 +158,13 @@ module Spree
|
|
|
223
158
|
Spree::Reporting::DefaultVocabulary.install(app.config.spree.reporting)
|
|
224
159
|
end
|
|
225
160
|
|
|
226
|
-
# We need to define promotions rules here so extensions and existing apps
|
|
227
|
-
# can add their custom classes on their initializer files
|
|
228
|
-
initializer 'spree.promo.environment' do |app|
|
|
229
|
-
app.config.spree.promotions = PromoEnvironment.new
|
|
230
|
-
app.config.spree.promotions.rules = []
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
initializer 'spree.promo.register.promotion.calculators' do |app|
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
# Pricing configuration for price lists and price rules
|
|
237
|
-
initializer 'spree.pricing.environment', after: 'spree.environment' do |app|
|
|
238
|
-
app.config.spree.pricing = PricingEnvironment.new
|
|
239
|
-
app.config.spree.pricing.rules = []
|
|
240
|
-
end
|
|
241
|
-
|
|
242
161
|
# Country and subdivision names are translated by the countries gem, which
|
|
243
162
|
# only loads the locales it is told about. This runs after initialization
|
|
244
163
|
# because Spree.available_locales reads i18n configuration that is not
|
|
245
164
|
# populated while initializers are still running.
|
|
246
165
|
config.after_initialize do
|
|
247
166
|
ISO3166.configure do |iso_config|
|
|
248
|
-
iso_config.locales = (Spree.
|
|
167
|
+
iso_config.locales = (Spree.configured_locales.map { |locale| locale.to_s.downcase } << 'en').uniq
|
|
249
168
|
end
|
|
250
169
|
|
|
251
170
|
Spree::IsoData.reset!
|
|
@@ -293,7 +212,6 @@ module Spree
|
|
|
293
212
|
Spree::Collection
|
|
294
213
|
]
|
|
295
214
|
|
|
296
|
-
|
|
297
215
|
# The fallback engine when a market names none (see docs/plans/6.0-tax-provider.md).
|
|
298
216
|
# Assigned only if an initializer file has not already named one — an app
|
|
299
217
|
# that picks its own default must keep it.
|
|
@@ -355,7 +273,6 @@ module Spree
|
|
|
355
273
|
'deutsche_post' => { name: 'Deutsche Post DHL', url: 'https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?piececode=:tracking' }
|
|
356
274
|
}
|
|
357
275
|
|
|
358
|
-
|
|
359
276
|
# Quoting strategies selectable on a delivery method. Internal prices
|
|
360
277
|
# through the method's calculator; carrier gems append theirs.
|
|
361
278
|
Rails.application.config.spree.delivery_rate_providers.concat [
|
|
@@ -603,33 +520,6 @@ module Spree
|
|
|
603
520
|
Spree.customer_class
|
|
604
521
|
]
|
|
605
522
|
|
|
606
|
-
Rails.application.config.spree.analytics_events = {
|
|
607
|
-
product_viewed: 'Product Viewed',
|
|
608
|
-
product_list_viewed: 'Product List Viewed',
|
|
609
|
-
product_searched: 'Product Searched',
|
|
610
|
-
product_added: 'Product Added',
|
|
611
|
-
product_removed: 'Product Removed',
|
|
612
|
-
|
|
613
|
-
product_added_to_wishlist: 'Product Added to Wishlist',
|
|
614
|
-
product_removed_from_wishlist: 'Product Removed from Wishlist',
|
|
615
|
-
|
|
616
|
-
subscribed_to_newsletter: 'Subscribed to Newsletter',
|
|
617
|
-
unsubscribed_from_newsletter: 'Unsubscribed from Newsletter',
|
|
618
|
-
|
|
619
|
-
payment_info_entered: 'Payment Info Entered',
|
|
620
|
-
coupon_entered: 'Coupon Entered',
|
|
621
|
-
coupon_removed: 'Coupon Removed',
|
|
622
|
-
coupon_applied: 'Coupon Applied',
|
|
623
|
-
coupon_denied: 'Coupon Denied',
|
|
624
|
-
|
|
625
|
-
checkout_started: 'Checkout Started',
|
|
626
|
-
checkout_email_entered: 'Checkout Email Entered',
|
|
627
|
-
checkout_step_viewed: 'Checkout Step Viewed',
|
|
628
|
-
checkout_step_completed: 'Checkout Step Completed',
|
|
629
|
-
order_completed: 'Order Completed',
|
|
630
|
-
}
|
|
631
|
-
Rails.application.config.spree.analytics_event_handlers = []
|
|
632
|
-
|
|
633
523
|
Rails.application.config.spree.integrations = []
|
|
634
524
|
|
|
635
525
|
Rails.application.config.spree.validators.addresses = [
|
|
@@ -648,6 +538,7 @@ module Spree
|
|
|
648
538
|
Spree::SellerTransferSubscriber,
|
|
649
539
|
Spree::SellerTransferReversalSubscriber,
|
|
650
540
|
Spree::ExportSubscriber,
|
|
541
|
+
Spree::ImportEmailSubscriber,
|
|
651
542
|
Spree::InvitationEmailSubscriber,
|
|
652
543
|
Spree::SellerOnboardingSubscriber,
|
|
653
544
|
Spree::AdminUserEmailSubscriber,
|
|
@@ -668,7 +559,23 @@ module Spree
|
|
|
668
559
|
)
|
|
669
560
|
end
|
|
670
561
|
|
|
671
|
-
|
|
562
|
+
# Deprecated constant aliases warn when their file loads. Leaving them
|
|
563
|
+
# out of eager loading keeps every boot quiet; they still load, and
|
|
564
|
+
# warn, the first time something references the old name.
|
|
565
|
+
DEPRECATED_ALIAS_FILES = %w[
|
|
566
|
+
app/models/concerns/spree/user_methods.rb
|
|
567
|
+
app/models/spree/asset.rb
|
|
568
|
+
app/models/spree/classification.rb
|
|
569
|
+
app/models/spree/promotion/rules/taxon.rb
|
|
570
|
+
app/models/spree/promotion_rule_taxon.rb
|
|
571
|
+
app/models/spree/return_authorization_reason.rb
|
|
572
|
+
app/models/spree/taxon.rb
|
|
573
|
+
app/services/spree/checkout/add_store_credit.rb
|
|
574
|
+
app/services/spree/checkout/remove_store_credit.rb
|
|
575
|
+
].freeze
|
|
576
|
+
|
|
577
|
+
initializer 'spree.deprecated_aliases.skip_eager_load' do
|
|
578
|
+
Rails.autoloaders.main.do_not_eager_load(*DEPRECATED_ALIAS_FILES.map { |path| root.join(path) })
|
|
672
579
|
end
|
|
673
580
|
|
|
674
581
|
# filter sensitive information during logging
|
|
@@ -684,6 +591,13 @@ module Spree
|
|
|
684
591
|
]
|
|
685
592
|
end
|
|
686
593
|
|
|
594
|
+
# Records which store owns every uploaded file, and reports attaching a
|
|
595
|
+
# file to another store's record (docs/plans/6.0-uploads-and-file-ownership.md).
|
|
596
|
+
initializer 'spree.active_storage.store_ownership' do
|
|
597
|
+
ActiveSupport.on_load(:active_storage_blob) { include Spree::Uploads::BlobStoreOwnership }
|
|
598
|
+
ActiveSupport.on_load(:active_storage_attachment) { include Spree::Uploads::AttachmentStoreCheck }
|
|
599
|
+
end
|
|
600
|
+
|
|
687
601
|
initializer 'spree.core.checking_migrations' do |app|
|
|
688
602
|
app.config.after_initialize do
|
|
689
603
|
Migrations.new(config, engine_name).check unless Rails.env.test? || Spree::Config.disable_migration_check
|
|
@@ -711,17 +625,10 @@ module Spree
|
|
|
711
625
|
end
|
|
712
626
|
|
|
713
627
|
config.to_prepare do
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
)
|
|
719
|
-
) - I18n.load_path))
|
|
720
|
-
|
|
721
|
-
# Load application's model / class decorators
|
|
722
|
-
Dir.glob(File.join(File.dirname(__FILE__), '../../../app/**/*_decorator*.rb')) do |c|
|
|
723
|
-
Rails.configuration.cache_classes ? require(c) : load(c)
|
|
724
|
-
end
|
|
628
|
+
I18n.load_path.unshift(*(Spree::Core::Engine.config.paths['config/locales'].existent - I18n.load_path))
|
|
629
|
+
|
|
630
|
+
ActsAsTaggableOn::Tag.include(Spree::RansackableAttributes)
|
|
631
|
+
ActsAsTaggableOn::Tag.whitelisted_ransackable_attributes = %w[id name]
|
|
725
632
|
|
|
726
633
|
# Reset and re-activate event subscribers on code reload
|
|
727
634
|
# activate! will register all subscribers from Spree.subscribers
|
|
@@ -194,6 +194,11 @@ module Spree
|
|
|
194
194
|
catalog.register_scope(:webhooks, group: :settings, resources: -> {
|
|
195
195
|
[Spree::WebhookEndpoint, Spree::WebhookDelivery]
|
|
196
196
|
})
|
|
197
|
+
# Separate from settings: a template writes what every customer receives,
|
|
198
|
+
# links included, so managing store settings does not grant it.
|
|
199
|
+
catalog.register_scope(:email_templates, group: :settings, resources: -> {
|
|
200
|
+
[Spree::EmailTemplate, Spree::EmailTemplateDraft, Spree::EmailTemplateRevision]
|
|
201
|
+
})
|
|
197
202
|
catalog.register_scope(:integrations, group: :settings, resources: -> { [Spree::Integration] })
|
|
198
203
|
|
|
199
204
|
catalog.register_scope(:api_keys, group: :access, resources: -> { [Spree::ApiKey] })
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Preferences
|
|
3
|
+
# Raised when a `preferences` payload does not match the schema its type
|
|
4
|
+
# declares. Each failure names the value by a JSON pointer into the
|
|
5
|
+
# payload, so a client can show it next to the field it belongs to.
|
|
6
|
+
class InvalidPreferences < StandardError
|
|
7
|
+
# @return [Array<Hash{Symbol => String}>] `{ pointer:, message: }` per failure
|
|
8
|
+
attr_reader :failures
|
|
9
|
+
|
|
10
|
+
# @param failures [Array<Hash{Symbol => String}>] pointers relative to the preferences object
|
|
11
|
+
# @param prefix [String] where the preferences object sits in the request
|
|
12
|
+
def initialize(failures, prefix: '/preferences')
|
|
13
|
+
@failures = failures.map { |failure| failure.merge(pointer: "#{prefix}#{failure[:pointer]}") }
|
|
14
|
+
super(@failures.map { |failure| "#{failure[:pointer]}: #{failure[:message]}" }.join('; '))
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
|
|
2
|
+
module Spree
|
|
3
|
+
module Preferences
|
|
4
|
+
# Converts preferences stored as YAML to JSON, for the 6.0 migration and the
|
|
5
|
+
# `spree:upgrade:preferences_json` safety net.
|
|
6
|
+
#
|
|
7
|
+
# Rows are read and written through the connection, never through models:
|
|
8
|
+
# a model would load the column through whichever coder the current code
|
|
9
|
+
# declares, which is the thing being converted. The only thing asked of a
|
|
10
|
+
# model class is which of its preferences are secrets, from its
|
|
11
|
+
# declarations alone.
|
|
12
|
+
class JsonConversion
|
|
13
|
+
PERMITTED_CLASSES = [
|
|
14
|
+
Symbol, BigDecimal, Date, Time,
|
|
15
|
+
ActiveSupport::TimeWithZone, ActiveSupport::TimeZone, ActiveSupport::HashWithIndifferentAccess
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
class UnreadableRowError < StandardError; end
|
|
19
|
+
|
|
20
|
+
# Whether a row's class keeps a tier ladder, which moves from a hash keyed
|
|
21
|
+
# by threshold to a list, because a JSON object key is always a string.
|
|
22
|
+
#
|
|
23
|
+
# @param model [Class, nil] the class the row's `type` names
|
|
24
|
+
# @return [Boolean]
|
|
25
|
+
def self.tiered_calculator?(model)
|
|
26
|
+
model.is_a?(Class) && model.include?(Spree::Calculator::Tiers)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
|
30
|
+
# @param log [#call, nil] receives a line for each row left as it was
|
|
31
|
+
def initialize(connection, log: nil)
|
|
32
|
+
@connection = connection
|
|
33
|
+
@log = log || ->(_message) {}
|
|
34
|
+
@models = Hash.new { |models, type| models[type] = type.presence&.safe_constantize }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Resolves a row's `type`, once per type for the life of the conversion.
|
|
38
|
+
#
|
|
39
|
+
# @param type [String, nil]
|
|
40
|
+
# @return [Class, nil]
|
|
41
|
+
def model_for(type)
|
|
42
|
+
@models[type]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @param table [String]
|
|
46
|
+
# @param id [Object] the row's primary key
|
|
47
|
+
# @param assignments [Hash{String => String}] column names and the values to write
|
|
48
|
+
def write(table, id, assignments)
|
|
49
|
+
arel_table = Arel::Table.new(table)
|
|
50
|
+
update = Arel::UpdateManager.new(arel_table).
|
|
51
|
+
set(assignments.map { |column, value| [arel_table[column], value] }).
|
|
52
|
+
where(arel_table[:id].eq(id))
|
|
53
|
+
connection.update(update)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Tables with a `preferences` column that a model storing Spree
|
|
57
|
+
# preferences reads — Spree's, an extension's, or the application's own.
|
|
58
|
+
# A table another library owns is left alone.
|
|
59
|
+
#
|
|
60
|
+
# @return [Array<String>]
|
|
61
|
+
def preference_tables
|
|
62
|
+
Rails.application.eager_load! if defined?(Rails.application) && Rails.application
|
|
63
|
+
# An anonymous class (a spec's throwaway model) has no name to derive a
|
|
64
|
+
# table from, and asking raises, so it is skipped.
|
|
65
|
+
owned = ActiveRecord::Base.descendants.filter_map do |model|
|
|
66
|
+
next if model.name.nil? || model.abstract_class? || !model.include?(Spree::Preferences::Preferable)
|
|
67
|
+
|
|
68
|
+
model.table_name
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
connection.tables.select { |table| owned.include?(table) && connection.column_exists?(table, :preferences) }.sort
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Whether the table's `preferences` column is still `text` and needs a
|
|
75
|
+
# JSON column in its place.
|
|
76
|
+
#
|
|
77
|
+
# @param table [String]
|
|
78
|
+
# @return [Boolean]
|
|
79
|
+
def text_column?(table)
|
|
80
|
+
connection.columns(table).find { |column| column.name == 'preferences' }&.type == :text
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Replaces a `text` preferences column with a JSON one (`jsonb` where the
|
|
84
|
+
# adapter has it), converting every row on the way.
|
|
85
|
+
#
|
|
86
|
+
# @param table [String]
|
|
87
|
+
# @return [Integer] the number of rows written
|
|
88
|
+
def convert_text_table(table)
|
|
89
|
+
type = connection.native_database_types.key?(:jsonb) ? :jsonb : :json
|
|
90
|
+
# Left behind by an earlier run that stopped on an unreadable row, on a
|
|
91
|
+
# database that cannot roll back schema changes.
|
|
92
|
+
connection.add_column(table, :preferences_json, type) unless connection.column_exists?(table, :preferences_json)
|
|
93
|
+
converted = convert_table(table, target: 'preferences_json')
|
|
94
|
+
connection.remove_column(table, :preferences)
|
|
95
|
+
connection.rename_column(table, :preferences_json, :preferences)
|
|
96
|
+
converted
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Converts every row of `table` whose `source` column holds YAML (as text,
|
|
100
|
+
# or wrapped in a JSON string) and writes the JSON to `target`. Secrets
|
|
101
|
+
# move to `secret_preferences` when the table has that column, and tier
|
|
102
|
+
# ladders change shape.
|
|
103
|
+
#
|
|
104
|
+
# @param table [String]
|
|
105
|
+
# @param source [String] the column to read
|
|
106
|
+
# @param target [String] the column to write, the same one for an in-place conversion
|
|
107
|
+
# @return [Integer] the number of rows written
|
|
108
|
+
def convert_table(table, source: 'preferences', target: 'preferences')
|
|
109
|
+
typed = connection.column_exists?(table, :type)
|
|
110
|
+
secrets_column = connection.column_exists?(table, :secret_preferences)
|
|
111
|
+
rows = rows_with(table, source, ['id', source, ('type' if typed)].compact)
|
|
112
|
+
|
|
113
|
+
rows.count do |row|
|
|
114
|
+
preferences, already_json = read(row[source], table, row['id'])
|
|
115
|
+
type = row['type'] if typed
|
|
116
|
+
# A tiered calculator whose class was not loaded when the migration
|
|
117
|
+
# ran keeps its hash, so a JSON row is still reshaped when it has one.
|
|
118
|
+
reshaped = reshape_tiers(preferences, model_for(type))
|
|
119
|
+
next false if already_json && source == target && !reshaped
|
|
120
|
+
|
|
121
|
+
secrets = secrets_column ? extract_secrets(preferences, type, table, row['id']) : {}
|
|
122
|
+
|
|
123
|
+
assignments = { target => JSON.generate(preferences) }
|
|
124
|
+
assignments['secret_preferences'] = JSON.generate(secrets) if secrets.any?
|
|
125
|
+
write(table, row['id'], assignments)
|
|
126
|
+
true
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
attr_reader :connection, :log
|
|
133
|
+
|
|
134
|
+
# @return [Array(Hash, Boolean)] the preferences, and whether they were already JSON
|
|
135
|
+
def read(raw, table, id)
|
|
136
|
+
decoded = raw.is_a?(String) ? decode_json(raw) : raw
|
|
137
|
+
return [decoded.to_h, true] if decoded.is_a?(Hash)
|
|
138
|
+
|
|
139
|
+
yaml = decoded.is_a?(String) ? decoded : raw
|
|
140
|
+
value = parse_yaml(yaml, table, id) || {}
|
|
141
|
+
raise UnreadableRowError, "#{table} row #{id}: preferences are not a hash" unless value.is_a?(Hash)
|
|
142
|
+
|
|
143
|
+
[value.as_json, false]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def decode_json(raw)
|
|
147
|
+
JSON.parse(raw)
|
|
148
|
+
rescue JSON::ParserError
|
|
149
|
+
nil
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def parse_yaml(text, table, id)
|
|
153
|
+
YAML.safe_load(text.to_s, permitted_classes: PERMITTED_CLASSES, aliases: true)
|
|
154
|
+
rescue Psych::Exception => e
|
|
155
|
+
raise UnreadableRowError, "#{table} row #{id}: #{e.message}. Fix or clear this row, then run the migration again."
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def reshape_tiers(preferences, model)
|
|
159
|
+
tiers = preferences['tiers']
|
|
160
|
+
return unless tiers.is_a?(Hash) && self.class.tiered_calculator?(model)
|
|
161
|
+
|
|
162
|
+
preferences['tiers'] = tiers.map { |threshold, value| { 'threshold' => threshold.to_s, 'value' => value.to_s } }.
|
|
163
|
+
sort_by { |tier| Spree::Calculator::Tiers.decimal(tier['threshold']) || 0 }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def extract_secrets(preferences, type, table, id)
|
|
167
|
+
model = model_for(type)
|
|
168
|
+
unless model.respond_to?(:secret_preference_names)
|
|
169
|
+
log.call("#{table} row #{id}: class #{type.inspect} is not loaded, so its secrets stay in preferences until it is")
|
|
170
|
+
return {}
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
names = model.secret_preference_names.map(&:to_s)
|
|
174
|
+
secrets = preferences.slice(*names)
|
|
175
|
+
names.each { |name| preferences.delete(name) }
|
|
176
|
+
secrets
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# The given columns of every row whose `present` column is not NULL.
|
|
180
|
+
def rows_with(table, present, columns)
|
|
181
|
+
arel_table = Arel::Table.new(table)
|
|
182
|
+
connection.select_all(arel_table.project(*columns.map { |column| arel_table[column] }).where(arel_table[present].not_eq(nil)))
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|