spree_core 5.2.6 → 5.3.0.rc1
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/app/helpers/spree/addresses_helper.rb +1 -23
- data/app/helpers/spree/base_helper.rb +25 -77
- data/app/helpers/spree/currency_helper.rb +2 -2
- data/app/helpers/spree/images_helper.rb +5 -0
- data/app/helpers/spree/mail_helper.rb +1 -1
- data/app/helpers/spree/products_helper.rb +1 -1
- data/app/jobs/spree/events/subscriber_job.rb +58 -0
- data/app/jobs/spree/products/refresh_metrics_job.rb +14 -0
- data/app/jobs/spree/products/touch_taxons_job.rb +0 -1
- data/app/jobs/spree/variants/touch_job.rb +9 -0
- data/app/models/concerns/spree/adjustment_source.rb +8 -0
- data/app/models/concerns/spree/parameterizable_name.rb +1 -1
- data/app/models/concerns/spree/product_scopes.rb +54 -8
- data/app/models/concerns/spree/publishable.rb +253 -0
- data/app/models/concerns/spree/unique_name.rb +1 -1
- data/app/models/concerns/spree/user_methods.rb +21 -1
- data/app/models/spree/ability.rb +3 -3
- data/app/models/spree/address.rb +0 -3
- data/app/models/spree/adjustable/promotion_accumulator.rb +1 -1
- data/app/models/spree/adjustment.rb +32 -6
- data/app/models/spree/asset.rb +6 -3
- data/app/models/spree/base.rb +3 -1
- data/app/models/spree/classification.rb +2 -2
- data/app/models/spree/credit_card.rb +0 -3
- data/app/models/spree/current.rb +24 -3
- data/app/models/spree/custom_domain.rb +1 -1
- data/app/models/spree/customer_group.rb +94 -0
- data/app/models/spree/customer_group_user.rb +16 -0
- data/app/models/spree/customer_return.rb +2 -3
- data/app/models/spree/digital.rb +2 -4
- data/app/models/spree/digital_link.rb +2 -3
- data/app/models/spree/event.rb +104 -0
- data/app/models/spree/export.rb +7 -1
- data/app/models/spree/gift_card.rb +13 -1
- data/app/models/spree/gift_card_batch.rb +3 -1
- data/app/models/spree/image.rb +20 -5
- data/app/models/spree/import.rb +17 -12
- data/app/models/spree/import_row.rb +13 -26
- data/app/models/spree/inventory_unit.rb +0 -3
- data/app/models/spree/invitation.rb +12 -6
- data/app/models/spree/line_item.rb +57 -4
- data/app/models/spree/newsletter_subscriber.rb +2 -0
- data/app/models/spree/option_type.rb +2 -5
- data/app/models/spree/option_value.rb +1 -4
- data/app/models/spree/order/checkout.rb +7 -2
- data/app/models/spree/order/emails.rb +3 -11
- data/app/models/spree/order/store_credit.rb +5 -1
- data/app/models/spree/order.rb +80 -31
- data/app/models/spree/order_updater.rb +28 -9
- data/app/models/spree/payment/custom_events.rb +37 -0
- data/app/models/spree/payment.rb +13 -4
- data/app/models/spree/payment_capture_event.rb +0 -4
- data/app/models/spree/payment_method.rb +1 -1
- data/app/models/spree/permission_sets/default_customer.rb +3 -3
- data/app/models/spree/policy.rb +1 -8
- data/app/models/spree/post.rb +2 -7
- data/app/models/spree/post_category.rb +2 -0
- data/app/models/spree/price.rb +8 -6
- data/app/models/spree/price_list.rb +263 -0
- data/app/models/spree/price_rule.rb +26 -0
- data/app/models/spree/price_rules/customer_group_rule.rb +21 -0
- data/app/models/spree/price_rules/user_rule.rb +19 -0
- data/app/models/spree/price_rules/volume_rule.rb +21 -0
- data/app/models/spree/price_rules/zone_rule.rb +19 -0
- data/app/models/spree/product.rb +117 -76
- data/app/models/spree/product_property.rb +2 -2
- data/app/models/spree/promotion/rules/customer_group.rb +22 -0
- data/app/models/spree/promotion/rules/user.rb +2 -2
- data/app/models/spree/promotion.rb +3 -4
- data/app/models/spree/promotion_handler/coupon.rb +3 -3
- data/app/models/spree/property.rb +3 -6
- data/app/models/spree/prototype.rb +0 -3
- data/app/models/spree/refund.rb +2 -3
- data/app/models/spree/reimbursement.rb +5 -3
- data/app/models/spree/report.rb +7 -1
- data/app/models/spree/reports/products_performance.rb +1 -1
- data/app/models/spree/reports/sales_total.rb +1 -1
- data/app/models/spree/return_authorization.rb +7 -3
- data/app/models/spree/return_item.rb +15 -4
- data/app/models/spree/shipment/custom_events.rb +47 -0
- data/app/models/spree/shipment.rb +12 -5
- data/app/models/spree/shipping_category.rb +0 -3
- data/app/models/spree/shipping_method.rb +0 -3
- data/app/models/spree/stock/quantifier.rb +1 -1
- data/app/models/spree/stock_item.rb +2 -0
- data/app/models/spree/stock_location.rb +0 -3
- data/app/models/spree/stock_movement/custom_events.rb +44 -0
- data/app/models/spree/stock_movement.rb +3 -0
- data/app/models/spree/stock_transfer.rb +2 -3
- data/app/models/spree/store.rb +64 -92
- data/app/models/spree/store_credit.rb +3 -4
- data/app/models/spree/store_product.rb +14 -0
- data/app/models/spree/subscriber.rb +186 -0
- data/app/models/spree/tax_category.rb +0 -4
- data/app/models/spree/tax_rate.rb +0 -3
- data/app/models/spree/taxon.rb +3 -36
- data/app/models/spree/taxonomy.rb +0 -3
- data/app/models/spree/variant.rb +114 -21
- data/app/models/spree/webhook_delivery.rb +60 -0
- data/app/models/spree/webhook_endpoint.rb +53 -0
- data/app/models/spree/wished_item.rb +2 -4
- data/app/models/spree/wishlist.rb +2 -3
- data/app/models/spree/zone.rb +0 -9
- data/app/paginators/spree/shared/paginate.rb +4 -0
- data/app/serializers/spree/events/asset_serializer.rb +22 -0
- data/app/serializers/spree/events/base_serializer.rb +61 -0
- data/app/serializers/spree/events/customer_return_serializer.rb +20 -0
- data/app/serializers/spree/events/digital_link_serializer.rb +20 -0
- data/app/serializers/spree/events/digital_serializer.rb +18 -0
- data/app/serializers/spree/events/export_serializer.rb +22 -0
- data/app/serializers/spree/events/gift_card_batch_serializer.rb +24 -0
- data/app/serializers/spree/events/gift_card_serializer.rb +29 -0
- data/app/serializers/spree/events/image_serializer.rb +9 -0
- data/app/serializers/spree/events/import_row_serializer.rb +23 -0
- data/app/serializers/spree/events/import_serializer.rb +24 -0
- data/app/serializers/spree/events/invitation_serializer.rb +28 -0
- data/app/serializers/spree/events/line_item_serializer.rb +31 -0
- data/app/serializers/spree/events/newsletter_subscriber_serializer.rb +21 -0
- data/app/serializers/spree/events/order_serializer.rb +39 -0
- data/app/serializers/spree/events/payment_serializer.rb +24 -0
- data/app/serializers/spree/events/post_category_serializer.rb +20 -0
- data/app/serializers/spree/events/post_serializer.rb +26 -0
- data/app/serializers/spree/events/price_serializer.rb +22 -0
- data/app/serializers/spree/events/product_serializer.rb +24 -0
- data/app/serializers/spree/events/promotion_serializer.rb +32 -0
- data/app/serializers/spree/events/refund_serializer.rb +23 -0
- data/app/serializers/spree/events/reimbursement_serializer.rb +22 -0
- data/app/serializers/spree/events/report_serializer.rb +23 -0
- data/app/serializers/spree/events/return_authorization_serializer.rb +22 -0
- data/app/serializers/spree/events/return_item_serializer.rb +27 -0
- data/app/serializers/spree/events/shipment_serializer.rb +24 -0
- data/app/serializers/spree/events/stock_item_serializer.rb +22 -0
- data/app/serializers/spree/events/stock_movement_serializer.rb +22 -0
- data/app/serializers/spree/events/stock_transfer_serializer.rb +22 -0
- data/app/serializers/spree/events/store_credit_serializer.rb +30 -0
- data/app/serializers/spree/events/user_serializer.rb +18 -0
- data/app/serializers/spree/events/variant_serializer.rb +34 -0
- data/app/serializers/spree/events/wished_item_serializer.rb +20 -0
- data/app/serializers/spree/events/wishlist_serializer.rb +22 -0
- data/app/services/spree/addresses/update.rb +1 -1
- data/app/services/spree/cart/add_item.rb +1 -1
- data/app/services/spree/coupon_codes/coupon_codes_handler.rb +2 -1
- data/app/services/spree/data_feeds/google/required_attributes.rb +4 -4
- data/app/services/spree/newsletter/verify.rb +5 -0
- data/app/services/spree/products/auto_match_taxons.rb +1 -1
- data/app/services/spree/seeds/all.rb +1 -1
- data/app/services/spree/taxons/add_products.rb +8 -4
- data/app/services/spree/taxons/regenerate_products.rb +8 -0
- data/app/services/spree/taxons/remove_products.rb +12 -7
- data/app/subscribers/spree/event_log_subscriber.rb +64 -0
- data/app/subscribers/spree/export_subscriber.rb +26 -0
- data/app/subscribers/spree/invitation_email_subscriber.rb +40 -0
- data/app/subscribers/spree/product_metrics_subscriber.rb +29 -0
- data/app/subscribers/spree/report_subscriber.rb +26 -0
- data/config/locales/en.yml +126 -0
- data/db/migrate/20251110120000_create_spree_price_lists.rb +22 -0
- data/db/migrate/20251110120001_create_spree_price_rules.rb +13 -0
- data/db/migrate/20251110120002_add_price_list_id_to_spree_prices.rb +6 -0
- data/db/migrate/20251110120003_add_price_list_id_to_spree_line_items.rb +5 -0
- data/db/migrate/20251201172118_fix_indexes_on_friendly_id_slugs.rb +8 -0
- data/db/migrate/20251214000001_create_spree_webhook_endpoints.rb +19 -0
- data/db/migrate/20251214000002_create_spree_webhook_deliveries.rb +23 -0
- data/db/migrate/20251222000000_add_performance_indexes_to_spree_adjustments.rb +25 -0
- data/db/migrate/20260112000000_fix_spree_prices_unique_indexes.rb +33 -0
- data/db/migrate/20260115120000_create_spree_customer_groups.rb +14 -0
- data/db/migrate/20260115120001_create_spree_customer_group_users.rb +14 -0
- data/db/migrate/20260117140831_remove_not_null_constraint_from_policy_name.rb +5 -0
- data/db/migrate/20260118120000_add_statistics_to_store_products.rb +11 -0
- data/db/migrate/20260119120000_add_counter_caches_to_spree_products.rb +9 -0
- data/db/migrate/20260119170000_add_counter_caches_to_spree_taxons.rb +9 -0
- data/db/migrate/20260120120000_add_image_count_to_spree_variants.rb +9 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +14 -2
- data/lib/spree/core/configuration.rb +1 -0
- data/lib/spree/core/controller_helpers/auth.rb +0 -15
- data/lib/spree/core/controller_helpers/currency.rb +13 -9
- data/lib/spree/core/controller_helpers/search.rb +1 -1
- data/lib/spree/core/controller_helpers/store.rb +5 -1
- data/lib/spree/core/engine.rb +61 -78
- data/lib/spree/core/importer/order.rb +1 -1
- data/lib/spree/core/importer/product.rb +1 -1
- data/lib/spree/core/preferences/preferable.rb +14 -1
- data/lib/spree/core/pricing/context.rb +63 -0
- data/lib/spree/core/pricing/resolver.rb +129 -0
- data/lib/spree/core/search/base.rb +1 -1
- data/lib/spree/core/token_generator.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +42 -47
- data/lib/spree/events/adapters/active_support_notifications.rb +112 -0
- data/lib/spree/events/adapters/base.rb +193 -0
- data/lib/spree/events/registry.rb +99 -0
- data/lib/spree/events.rb +240 -0
- data/lib/spree/permitted_attributes.rb +13 -2
- data/lib/spree/testing_support/common_rake.rb +68 -35
- data/lib/spree/testing_support/factories/customer_group_factory.rb +6 -0
- data/lib/spree/testing_support/factories/customer_group_user_factory.rb +6 -0
- data/lib/spree/testing_support/factories/price_factory.rb +4 -0
- data/lib/spree/testing_support/factories/price_list_factory.rb +34 -0
- data/lib/spree/testing_support/factories/price_rule_factory.rb +49 -0
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +12 -0
- data/lib/spree/testing_support/factories/stock_item_factory.rb +6 -4
- data/lib/spree/testing_support/factories/store_product_factory.rb +6 -0
- data/lib/spree/testing_support/factories/taxon_factory.rb +0 -1
- data/lib/spree/testing_support/factories/webhook_delivery_factory.rb +48 -0
- data/lib/spree/testing_support/factories/webhook_endpoint_factory.rb +22 -0
- data/lib/spree/testing_support/lifecycle_events.rb +38 -0
- data/lib/spree/testing_support/store.rb +4 -2
- data/lib/spree/webhooks.rb +22 -0
- data/lib/tasks/products.rake +40 -0
- data/lib/tasks/taxons.rake +19 -0
- data/lib/tasks/variants.rake +18 -0
- metadata +112 -114
- data/app/jobs/spree/themes/duplicate_components_job.rb +0 -59
- data/app/jobs/spree/themes/screenshot_job.rb +0 -81
- data/app/models/concerns/spree/has_page_links.rb +0 -53
- data/app/models/spree/page.rb +0 -188
- data/app/models/spree/page_block.rb +0 -73
- data/app/models/spree/page_blocks/buttons.rb +0 -29
- data/app/models/spree/page_blocks/heading.rb +0 -18
- data/app/models/spree/page_blocks/image.rb +0 -20
- data/app/models/spree/page_blocks/link.rb +0 -21
- data/app/models/spree/page_blocks/mega_nav.rb +0 -33
- data/app/models/spree/page_blocks/mega_nav_with_subcategories.rb +0 -32
- data/app/models/spree/page_blocks/metafields.rb +0 -18
- data/app/models/spree/page_blocks/nav.rb +0 -15
- data/app/models/spree/page_blocks/newsletter_form.rb +0 -18
- data/app/models/spree/page_blocks/products/brand.rb +0 -15
- data/app/models/spree/page_blocks/products/buy_buttons.rb +0 -24
- data/app/models/spree/page_blocks/products/description.rb +0 -18
- data/app/models/spree/page_blocks/products/price.rb +0 -18
- data/app/models/spree/page_blocks/products/quantity_selector.rb +0 -20
- data/app/models/spree/page_blocks/products/share.rb +0 -8
- data/app/models/spree/page_blocks/products/title.rb +0 -19
- data/app/models/spree/page_blocks/products/variant_picker.rb +0 -13
- data/app/models/spree/page_blocks/subheading.rb +0 -17
- data/app/models/spree/page_blocks/text.rb +0 -16
- data/app/models/spree/page_link.rb +0 -60
- data/app/models/spree/page_section.rb +0 -222
- data/app/models/spree/page_sections/announcement_bar.rb +0 -28
- data/app/models/spree/page_sections/breadcrumbs.rb +0 -12
- data/app/models/spree/page_sections/collection_banner.rb +0 -18
- data/app/models/spree/page_sections/custom_code.rb +0 -11
- data/app/models/spree/page_sections/featured_posts.rb +0 -45
- data/app/models/spree/page_sections/featured_product.rb +0 -50
- data/app/models/spree/page_sections/featured_taxon.rb +0 -90
- data/app/models/spree/page_sections/featured_taxons.rb +0 -45
- data/app/models/spree/page_sections/footer.rb +0 -101
- data/app/models/spree/page_sections/header.rb +0 -62
- data/app/models/spree/page_sections/image_banner.rb +0 -55
- data/app/models/spree/page_sections/image_with_text.rb +0 -65
- data/app/models/spree/page_sections/main_password_footer.rb +0 -18
- data/app/models/spree/page_sections/main_password_header.rb +0 -20
- data/app/models/spree/page_sections/newsletter.rb +0 -54
- data/app/models/spree/page_sections/page_title.rb +0 -19
- data/app/models/spree/page_sections/post_details.rb +0 -19
- data/app/models/spree/page_sections/post_grid.rb +0 -19
- data/app/models/spree/page_sections/product_details.rb +0 -53
- data/app/models/spree/page_sections/product_grid.rb +0 -13
- data/app/models/spree/page_sections/related_products.rb +0 -58
- data/app/models/spree/page_sections/rich_text.rb +0 -31
- data/app/models/spree/page_sections/taxon_banner.rb +0 -18
- data/app/models/spree/page_sections/taxon_grid.rb +0 -17
- data/app/models/spree/page_sections/video.rb +0 -107
- data/app/models/spree/pages/account.rb +0 -19
- data/app/models/spree/pages/cart.rb +0 -19
- data/app/models/spree/pages/checkout.rb +0 -15
- data/app/models/spree/pages/custom.rb +0 -38
- data/app/models/spree/pages/homepage.rb +0 -72
- data/app/models/spree/pages/login.rb +0 -19
- data/app/models/spree/pages/password.rb +0 -59
- data/app/models/spree/pages/post.rb +0 -27
- data/app/models/spree/pages/post_list.rb +0 -36
- data/app/models/spree/pages/product_details.rb +0 -30
- data/app/models/spree/pages/search_results.rb +0 -43
- data/app/models/spree/pages/shop_all.rb +0 -40
- data/app/models/spree/pages/taxon.rb +0 -29
- data/app/models/spree/pages/taxon_list.rb +0 -41
- data/app/models/spree/pages/wishlist.rb +0 -15
- data/app/models/spree/theme.rb +0 -233
- data/app/models/spree/themes/default.rb +0 -97
- data/app/services/spree/taxons/touch_featured_sections.rb +0 -21
- data/db/migrate/20250120094216_create_page_builder_models.rb +0 -78
- data/db/migrate/20250305121352_remove_page_builder_indices.rb +0 -11
- data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +0 -7
- data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +0 -10
- data/lib/generators/spree/dummy/templates/initializers/devise.rb +0 -3
- data/lib/generators/spree/install/install_generator.rb +0 -219
- data/lib/generators/spree/install/templates/config/initializers/spree.rb +0 -126
- data/lib/spree/core/webhooks.rb +0 -21
- data/lib/spree/testing_support/factories/page_block_factory.rb +0 -22
- data/lib/spree/testing_support/factories/page_factory.rb +0 -33
- data/lib/spree/testing_support/factories/page_link_factory.rb +0 -7
- data/lib/spree/testing_support/factories/page_section_factory.rb +0 -27
- data/lib/spree/testing_support/factories/theme_factory.rb +0 -14
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class AddStatisticsToStoreProducts < ActiveRecord::Migration[7.0]
|
|
2
|
+
def change
|
|
3
|
+
add_column :spree_products_stores, :units_sold_count, :integer, default: 0, null: false, if_not_exists: true
|
|
4
|
+
add_column :spree_products_stores, :revenue, :decimal, precision: 10, scale: 2, default: 0, null: false, if_not_exists: true
|
|
5
|
+
|
|
6
|
+
add_index :spree_products_stores, [:store_id, :units_sold_count],
|
|
7
|
+
name: 'index_products_stores_on_store_and_units_sold', if_not_exists: true
|
|
8
|
+
add_index :spree_products_stores, [:store_id, :revenue],
|
|
9
|
+
name: 'index_products_stores_on_store_and_revenue', if_not_exists: true
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class AddCounterCachesToSpreeProducts < ActiveRecord::Migration[7.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :spree_products, :variant_count, :integer, default: 0, null: false, if_not_exists: true
|
|
4
|
+
add_column :spree_products, :classification_count, :integer, default: 0, null: false, if_not_exists: true
|
|
5
|
+
|
|
6
|
+
add_index :spree_products, :variant_count, if_not_exists: true
|
|
7
|
+
add_index :spree_products, :classification_count, if_not_exists: true
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class AddCounterCachesToSpreeTaxons < ActiveRecord::Migration[7.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :spree_taxons, :children_count, :integer, default: 0, null: false, if_not_exists: true
|
|
4
|
+
add_column :spree_taxons, :classification_count, :integer, default: 0, null: false, if_not_exists: true
|
|
5
|
+
|
|
6
|
+
add_index :spree_taxons, :children_count, if_not_exists: true
|
|
7
|
+
add_index :spree_taxons, :classification_count, if_not_exists: true
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class AddImageCountToSpreeVariants < ActiveRecord::Migration[7.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :spree_variants, :image_count, :integer, default: 0, null: false, if_not_exists: true
|
|
4
|
+
add_column :spree_products, :total_image_count, :integer, default: 0, null: false, if_not_exists: true
|
|
5
|
+
|
|
6
|
+
add_index :spree_variants, :image_count, if_not_exists: true
|
|
7
|
+
add_index :spree_products, :total_image_count, if_not_exists: true
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -11,6 +11,8 @@ module Spree
|
|
|
11
11
|
class_option :lib_name, default: ''
|
|
12
12
|
class_option :database, default: ''
|
|
13
13
|
class_option :api, type: :boolean, default: false
|
|
14
|
+
class_option :javascript, type: :boolean, default: false
|
|
15
|
+
class_option :css, type: :string, default: ''
|
|
14
16
|
|
|
15
17
|
def self.source_paths
|
|
16
18
|
paths = superclass.source_paths
|
|
@@ -24,12 +26,22 @@ module Spree
|
|
|
24
26
|
|
|
25
27
|
def generate_test_dummy
|
|
26
28
|
puts 'Generating dummy Rails application...'
|
|
29
|
+
puts "Options: #{options.inspect}"
|
|
27
30
|
|
|
28
31
|
args = [File.expand_path(dummy_path, destination_root)]
|
|
29
32
|
|
|
30
33
|
# Database
|
|
31
34
|
args << "--database=#{options[:database].presence || 'sqlite3'}"
|
|
32
35
|
|
|
36
|
+
# CSS framework (e.g., tailwind)
|
|
37
|
+
args << "--css=#{options[:css]}" if options[:css].present?
|
|
38
|
+
|
|
39
|
+
# JavaScript
|
|
40
|
+
args << '--skip-javascript' unless options[:javascript]
|
|
41
|
+
|
|
42
|
+
# Skip asset pipeline if no javascript or css is required
|
|
43
|
+
args << '--skip-asset-pipeline' unless options[:javascript] || options[:css].present?
|
|
44
|
+
|
|
33
45
|
# Skip options
|
|
34
46
|
args << '--force'
|
|
35
47
|
args << '--skip-bundle'
|
|
@@ -55,6 +67,7 @@ module Spree
|
|
|
55
67
|
# API mode (implies skip-asset-pipeline, skip-javascript, skip-hotwire)
|
|
56
68
|
args << '--api' if options[:api]
|
|
57
69
|
|
|
70
|
+
puts "Rails app generator args: #{args.inspect}"
|
|
58
71
|
Rails::Generators.invoke('app', args)
|
|
59
72
|
inject_yaml_permitted_classes
|
|
60
73
|
end
|
|
@@ -68,7 +81,6 @@ module Spree
|
|
|
68
81
|
template 'rails/application.rb', "#{dummy_path}/config/application.rb", force: true
|
|
69
82
|
template 'rails/routes.rb', "#{dummy_path}/config/routes.rb", force: true
|
|
70
83
|
template 'rails/test.rb', "#{dummy_path}/config/environments/test.rb", force: true
|
|
71
|
-
template 'initializers/devise.rb', "#{dummy_path}/config/initializers/devise.rb", force: true
|
|
72
84
|
template "app/assets/config/manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true unless options[:api]
|
|
73
85
|
end
|
|
74
86
|
|
|
@@ -94,7 +106,7 @@ module Spree
|
|
|
94
106
|
def inject_yaml_permitted_classes
|
|
95
107
|
inside dummy_path do
|
|
96
108
|
inject_into_file 'config/application.rb', %Q[
|
|
97
|
-
config.active_record.yaml_column_permitted_classes = [Symbol, BigDecimal, ActiveSupport::HashWithIndifferentAccess]
|
|
109
|
+
config.active_record.yaml_column_permitted_classes = [Symbol, BigDecimal, ActiveSupport::HashWithIndifferentAccess, ActiveSupport::TimeWithZone]
|
|
98
110
|
], after: /config\.load_defaults.*$/, verbose: true
|
|
99
111
|
end
|
|
100
112
|
end
|
|
@@ -42,6 +42,7 @@ module Spree
|
|
|
42
42
|
preference :credit_to_new_allocation, :boolean, default: false
|
|
43
43
|
preference :disable_sku_validation, :boolean, default: false # when turned off disables the built-in SKU uniqueness validation
|
|
44
44
|
preference :disable_store_presence_validation, :boolean, default: false # when turned off disables Store presence validation for Products and Payment Methods
|
|
45
|
+
preference :events_log_enabled, :boolean, default: true # Log all Spree events to Rails logger
|
|
45
46
|
preference :expedited_exchanges, :boolean, default: false # NOTE this requires payment profiles to be supported on your gateway of choice as well as a delayed job handler to be configured with activejob. kicks off an exchange shipment upon return authorization save. charge customer if they do not return items within timely manner.
|
|
46
47
|
preference :expedited_exchanges_days_window, :integer, default: 14 # the amount of days the customer has to return their item after the expedited exchange is shipped in order to avoid being charged
|
|
47
48
|
preference :geocode_addresses, :boolean, default: true
|
|
@@ -20,21 +20,6 @@ module Spree
|
|
|
20
20
|
@current_ability ||= Spree.ability_class.new(try_spree_current_user, { store: current_store })
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def redirect_back_or_default(default)
|
|
24
|
-
Spree::Deprecation.warn('redirect_back_or_default is deprecated and will be removed in Spree 5.2. Please use redirect_back(fallback_location: default) instead.')
|
|
25
|
-
redirect_back(fallback_location: default)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def set_token
|
|
29
|
-
Spree::Deprecation.warn('set_token is deprecated and will be removed in Spree 5.2. Please use create_token_cookie(token) instead.')
|
|
30
|
-
cookies.permanent.signed[:token] ||= cookies.signed[:guest_token]
|
|
31
|
-
cookies.permanent.signed[:token] ||= {
|
|
32
|
-
value: generate_token,
|
|
33
|
-
httponly: true
|
|
34
|
-
}
|
|
35
|
-
cookies.permanent.signed[:guest_token] ||= cookies.permanent.signed[:token]
|
|
36
|
-
end
|
|
37
|
-
|
|
38
23
|
def current_oauth_token
|
|
39
24
|
get_last_access_token = ->(user) { Spree::OauthAccessToken.active_for(user).where(expires_in: nil).last }
|
|
40
25
|
create_access_token = ->(user) { Spree::OauthAccessToken.create!(resource_owner: user) }
|
|
@@ -17,15 +17,19 @@ module Spree
|
|
|
17
17
|
# Returns the currently selected currency.
|
|
18
18
|
# @return [String] the currently selected currency, eg. `USD`
|
|
19
19
|
def current_currency
|
|
20
|
-
@current_currency ||=
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
@current_currency ||= begin
|
|
21
|
+
currency = if defined?(session) && session.key?(:currency) && supported_currency?(session[:currency])
|
|
22
|
+
session[:currency]
|
|
23
|
+
elsif params[:currency].present? && supported_currency?(params[:currency])
|
|
24
|
+
params[:currency]
|
|
25
|
+
elsif current_store.present?
|
|
26
|
+
current_store.default_currency
|
|
27
|
+
else
|
|
28
|
+
Spree::Store.default.default_currency
|
|
29
|
+
end&.upcase
|
|
30
|
+
Spree::Current.currency = currency
|
|
31
|
+
currency
|
|
32
|
+
end
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
# Returns the list of supported currencies for the current store.
|
|
@@ -3,7 +3,7 @@ module Spree
|
|
|
3
3
|
module ControllerHelpers
|
|
4
4
|
module Search
|
|
5
5
|
def build_searcher(params)
|
|
6
|
-
Spree::Deprecation.warn("Spree::Core::ControllerHelpers::Search is deprecated and will be removed in Spree
|
|
6
|
+
Spree::Deprecation.warn("Spree::Core::ControllerHelpers::Search is deprecated and will be removed in Spree 5.5.")
|
|
7
7
|
|
|
8
8
|
Spree.searcher_class.new(params).tap do |searcher|
|
|
9
9
|
searcher.current_user = try_spree_current_user
|
|
@@ -60,7 +60,11 @@ module Spree
|
|
|
60
60
|
private
|
|
61
61
|
|
|
62
62
|
def current_tax_zone
|
|
63
|
-
@current_tax_zone ||=
|
|
63
|
+
@current_tax_zone ||= begin
|
|
64
|
+
zone = @current_order&.tax_zone || Spree::Zone.default_tax || current_store.checkout_zone
|
|
65
|
+
Spree::Current.zone = zone
|
|
66
|
+
zone
|
|
67
|
+
end
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
def current_store_finder
|
data/lib/spree/core/engine.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Spree
|
|
|
12
12
|
:adjusters,
|
|
13
13
|
:stock_splitters,
|
|
14
14
|
:promotions,
|
|
15
|
+
:pricing,
|
|
15
16
|
:line_item_comparison_hooks,
|
|
16
17
|
:data_feed_types,
|
|
17
18
|
:export_types,
|
|
@@ -27,14 +28,19 @@ module Spree
|
|
|
27
28
|
:metafields,
|
|
28
29
|
:analytics_events,
|
|
29
30
|
:analytics_event_handlers,
|
|
30
|
-
:integrations
|
|
31
|
+
:integrations,
|
|
32
|
+
:subscribers)
|
|
31
33
|
SpreeCalculators = Struct.new(:shipping_methods, :tax_rates, :promotion_actions_create_adjustments, :promotion_actions_create_item_adjustments)
|
|
32
34
|
PromoEnvironment = Struct.new(:rules, :actions)
|
|
35
|
+
PricingEnvironment = Struct.new(:rules)
|
|
33
36
|
SpreeValidators = Struct.new(:addresses)
|
|
34
37
|
MetafieldsEnvironment = Struct.new(:types, :enabled_resources)
|
|
35
38
|
isolate_namespace Spree
|
|
36
39
|
engine_name 'spree'
|
|
37
40
|
|
|
41
|
+
# Add app/subscribers to autoload paths
|
|
42
|
+
config.paths.add 'app/subscribers', eager_load: true
|
|
43
|
+
|
|
38
44
|
rake_tasks do
|
|
39
45
|
load File.join(root, 'lib', 'tasks', 'exchanges.rake')
|
|
40
46
|
end
|
|
@@ -43,13 +49,18 @@ module Spree
|
|
|
43
49
|
app.config.spree = Environment.new(SpreeCalculators.new, SpreeValidators.new, Spree::Core::Configuration.new, Spree::Core::Dependencies.new)
|
|
44
50
|
|
|
45
51
|
app.config.active_record.yaml_column_permitted_classes ||= []
|
|
46
|
-
app.config.active_record.yaml_column_permitted_classes.concat([Symbol, BigDecimal, ActiveSupport::HashWithIndifferentAccess])
|
|
52
|
+
app.config.active_record.yaml_column_permitted_classes.concat([Symbol, BigDecimal, ActiveSupport::HashWithIndifferentAccess, ActiveSupport::TimeWithZone])
|
|
47
53
|
Spree::Config = app.config.spree.preferences
|
|
48
54
|
Spree::RuntimeConfig = app.config.spree.preferences # for compatibility
|
|
49
55
|
Spree::Dependencies = app.config.spree.dependencies
|
|
50
56
|
Spree::Deprecation = ActiveSupport::Deprecation.new('6.0', 'Spree')
|
|
51
57
|
end
|
|
52
58
|
|
|
59
|
+
initializer 'spree.register.subscribers', before: :load_config_initializers do |app|
|
|
60
|
+
# Initialize subscribers array early so engines can add subscribers via initializers
|
|
61
|
+
app.config.spree.subscribers = []
|
|
62
|
+
end
|
|
63
|
+
|
|
53
64
|
initializer 'spree.register.calculators', before: :after_initialize do |app|
|
|
54
65
|
end
|
|
55
66
|
|
|
@@ -82,6 +93,12 @@ module Spree
|
|
|
82
93
|
initializer 'spree.promo.register.promotion.calculators' do |app|
|
|
83
94
|
end
|
|
84
95
|
|
|
96
|
+
# Pricing configuration for price lists and price rules
|
|
97
|
+
initializer 'spree.pricing.environment', after: 'spree.environment' do |app|
|
|
98
|
+
app.config.spree.pricing = PricingEnvironment.new
|
|
99
|
+
app.config.spree.pricing.rules = []
|
|
100
|
+
end
|
|
101
|
+
|
|
85
102
|
# Promotion rules need to be evaluated on after initialize otherwise
|
|
86
103
|
# Spree.user_class would be nil and users might experience errors related
|
|
87
104
|
# to malformed model associations (Spree.user_class is only defined on
|
|
@@ -139,6 +156,7 @@ module Spree
|
|
|
139
156
|
Spree::Promotion::Rules::ItemTotal,
|
|
140
157
|
Spree::Promotion::Rules::Product,
|
|
141
158
|
Spree::Promotion::Rules::User,
|
|
159
|
+
Spree::Promotion::Rules::CustomerGroup,
|
|
142
160
|
Spree::Promotion::Rules::FirstOrder,
|
|
143
161
|
Spree::Promotion::Rules::UserLoggedIn,
|
|
144
162
|
Spree::Promotion::Rules::OneUsePerUser,
|
|
@@ -146,6 +164,13 @@ module Spree
|
|
|
146
164
|
Spree::Promotion::Rules::OptionValue,
|
|
147
165
|
]
|
|
148
166
|
|
|
167
|
+
Rails.application.config.spree.pricing.rules.concat [
|
|
168
|
+
Spree::PriceRules::ZoneRule,
|
|
169
|
+
Spree::PriceRules::UserRule,
|
|
170
|
+
Spree::PriceRules::CustomerGroupRule,
|
|
171
|
+
Spree::PriceRules::VolumeRule
|
|
172
|
+
]
|
|
173
|
+
|
|
149
174
|
Rails.application.config.spree.promotions.actions = [
|
|
150
175
|
Promotion::Actions::CreateAdjustment,
|
|
151
176
|
Promotion::Actions::CreateItemAdjustments,
|
|
@@ -175,82 +200,6 @@ module Spree
|
|
|
175
200
|
Spree::TaxonRules::Sale,
|
|
176
201
|
]
|
|
177
202
|
|
|
178
|
-
Rails.application.config.spree.themes = [
|
|
179
|
-
Spree::Themes::Default
|
|
180
|
-
]
|
|
181
|
-
|
|
182
|
-
Rails.application.config.spree.theme_layout_sections = [
|
|
183
|
-
Spree::PageSections::AnnouncementBar,
|
|
184
|
-
Spree::PageSections::Header,
|
|
185
|
-
Spree::PageSections::Newsletter,
|
|
186
|
-
Spree::PageSections::Footer
|
|
187
|
-
]
|
|
188
|
-
|
|
189
|
-
Rails.application.config.spree.pages = [
|
|
190
|
-
Spree::Pages::Cart,
|
|
191
|
-
Spree::Pages::Post,
|
|
192
|
-
Spree::Pages::TaxonList,
|
|
193
|
-
Spree::Pages::Custom,
|
|
194
|
-
Spree::Pages::ProductDetails,
|
|
195
|
-
Spree::Pages::ShopAll,
|
|
196
|
-
Spree::Pages::Taxon,
|
|
197
|
-
Spree::Pages::Wishlist,
|
|
198
|
-
Spree::Pages::SearchResults,
|
|
199
|
-
Spree::Pages::Checkout,
|
|
200
|
-
Spree::Pages::Password,
|
|
201
|
-
Spree::Pages::Homepage,
|
|
202
|
-
Spree::Pages::Login,
|
|
203
|
-
Spree::Pages::PostList,
|
|
204
|
-
Spree::Pages::Account
|
|
205
|
-
]
|
|
206
|
-
|
|
207
|
-
Rails.application.config.spree.page_sections = [
|
|
208
|
-
Spree::PageSections::Breadcrumbs,
|
|
209
|
-
Spree::PageSections::FeaturedPosts,
|
|
210
|
-
Spree::PageSections::TaxonGrid,
|
|
211
|
-
Spree::PageSections::ImageWithText,
|
|
212
|
-
Spree::PageSections::FeaturedTaxon,
|
|
213
|
-
Spree::PageSections::CollectionBanner,
|
|
214
|
-
Spree::PageSections::ProductDetails,
|
|
215
|
-
Spree::PageSections::MainPasswordFooter,
|
|
216
|
-
Spree::PageSections::RelatedProducts,
|
|
217
|
-
Spree::PageSections::CustomCode,
|
|
218
|
-
Spree::PageSections::TaxonBanner,
|
|
219
|
-
Spree::PageSections::FeaturedProduct,
|
|
220
|
-
Spree::PageSections::ProductGrid,
|
|
221
|
-
Spree::PageSections::ImageBanner,
|
|
222
|
-
Spree::PageSections::PageTitle,
|
|
223
|
-
Spree::PageSections::MainPasswordHeader,
|
|
224
|
-
Spree::PageSections::PostDetails,
|
|
225
|
-
Spree::PageSections::PostGrid,
|
|
226
|
-
Spree::PageSections::FeaturedTaxons,
|
|
227
|
-
Spree::PageSections::RichText,
|
|
228
|
-
Spree::PageSections::Video,
|
|
229
|
-
Spree::PageSections::Footer,
|
|
230
|
-
Spree::PageSections::Newsletter,
|
|
231
|
-
Spree::PageSections::Header,
|
|
232
|
-
Spree::PageSections::AnnouncementBar
|
|
233
|
-
]
|
|
234
|
-
|
|
235
|
-
Rails.application.config.spree.page_blocks = [
|
|
236
|
-
Spree::PageBlocks::Link,
|
|
237
|
-
Spree::PageBlocks::MegaNav,
|
|
238
|
-
Spree::PageBlocks::MegaNavWithSubcategories,
|
|
239
|
-
Spree::PageBlocks::Subheading,
|
|
240
|
-
Spree::PageBlocks::Heading,
|
|
241
|
-
Spree::PageBlocks::Nav,
|
|
242
|
-
Spree::PageBlocks::Buttons,
|
|
243
|
-
Spree::PageBlocks::Text,
|
|
244
|
-
Spree::PageBlocks::NewsletterForm,
|
|
245
|
-
Spree::PageBlocks::Image,
|
|
246
|
-
Spree::PageBlocks::Products::Title,
|
|
247
|
-
Spree::PageBlocks::Products::Share,
|
|
248
|
-
Spree::PageBlocks::Products::Price,
|
|
249
|
-
Spree::PageBlocks::Products::QuantitySelector,
|
|
250
|
-
Spree::PageBlocks::Products::VariantPicker,
|
|
251
|
-
Spree::PageBlocks::Products::BuyButtons
|
|
252
|
-
]
|
|
253
|
-
|
|
254
203
|
Rails.application.config.spree.reports = [
|
|
255
204
|
Spree::Reports::ProductsPerformance,
|
|
256
205
|
Spree::Reports::SalesTotal
|
|
@@ -341,6 +290,20 @@ module Spree
|
|
|
341
290
|
Rails.application.config.spree.validators.addresses = [
|
|
342
291
|
Spree::Addresses::PhoneValidator
|
|
343
292
|
]
|
|
293
|
+
|
|
294
|
+
# Attach event log subscriber if enabled
|
|
295
|
+
if Spree::Config.events_log_enabled
|
|
296
|
+
Spree::EventLogSubscriber.attach_to_notifications
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Add core event subscribers
|
|
300
|
+
# Other engines add their subscribers in their own after_initialize blocks
|
|
301
|
+
Spree.subscribers.concat [
|
|
302
|
+
Spree::ExportSubscriber,
|
|
303
|
+
Spree::ReportSubscriber,
|
|
304
|
+
Spree::InvitationEmailSubscriber,
|
|
305
|
+
Spree::ProductMetricsSubscriber
|
|
306
|
+
]
|
|
344
307
|
end
|
|
345
308
|
|
|
346
309
|
initializer 'spree.promo.register.promotions.actions' do |app|
|
|
@@ -379,6 +342,15 @@ module Spree
|
|
|
379
342
|
end
|
|
380
343
|
end
|
|
381
344
|
|
|
345
|
+
# Activate event subscribers after all engines have registered their subscribers
|
|
346
|
+
# This registers an after_initialize callback late, ensuring it runs after all engine callbacks
|
|
347
|
+
# Needed for console, jobs, and other contexts where to_prepare doesn't run
|
|
348
|
+
initializer 'spree.events.schedule_activation', after: :load_config_initializers do |app|
|
|
349
|
+
app.config.after_initialize do
|
|
350
|
+
Spree::Events.activate!
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
382
354
|
config.to_prepare do
|
|
383
355
|
# Ensure spree locale paths are present before decorators
|
|
384
356
|
I18n.load_path.unshift(*(Dir.glob(
|
|
@@ -391,6 +363,17 @@ module Spree
|
|
|
391
363
|
Dir.glob(File.join(File.dirname(__FILE__), '../../../app/**/*_decorator*.rb')) do |c|
|
|
392
364
|
Rails.configuration.cache_classes ? require(c) : load(c)
|
|
393
365
|
end
|
|
366
|
+
|
|
367
|
+
# Reset and re-activate event subscribers on code reload
|
|
368
|
+
# activate! will register all subscribers from Spree.subscribers
|
|
369
|
+
# Note: resolve_subscriber in register_subscribers! handles stale class references
|
|
370
|
+
Spree::Events.reset!
|
|
371
|
+
Spree::Events.activate!
|
|
372
|
+
|
|
373
|
+
# Re-attach event log subscriber if enabled
|
|
374
|
+
if Spree::Config.events_log_enabled
|
|
375
|
+
Spree::EventLogSubscriber.attach_to_notifications
|
|
376
|
+
end
|
|
394
377
|
end
|
|
395
378
|
end
|
|
396
379
|
end
|
|
@@ -3,7 +3,7 @@ module Spree
|
|
|
3
3
|
module Importer
|
|
4
4
|
class Order
|
|
5
5
|
def self.import(user, params)
|
|
6
|
-
Spree::Deprecation.warn('Spree::Core::Importer::Order is deprecated and will be removed in Spree
|
|
6
|
+
Spree::Deprecation.warn('Spree::Core::Importer::Order is deprecated and will be removed in Spree 5.5. Please use `Spree::Imports::Order` instead.')
|
|
7
7
|
|
|
8
8
|
ensure_country_id_from_params params[:ship_address_attributes]
|
|
9
9
|
ensure_state_id_from_params params[:ship_address_attributes]
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
attr_reader :product, :product_attrs, :variants_attrs, :options_attrs, :store
|
|
6
6
|
|
|
7
7
|
def initialize(product, product_params, options = {})
|
|
8
|
-
Spree::Deprecation.warn('Spree::Core::Importer::Product is deprecated and will be removed in Spree
|
|
8
|
+
Spree::Deprecation.warn('Spree::Core::Importer::Product is deprecated and will be removed in Spree 5.5. Please use `Spree::Imports::Product` instead.')
|
|
9
9
|
|
|
10
10
|
@store = options[:store] || Spree::Store.default
|
|
11
11
|
@product = product || Spree::Product.new(product_params)
|
|
@@ -131,7 +131,9 @@ module Spree::Preferences::Preferable
|
|
|
131
131
|
decimal_value ||= 0 unless nullable
|
|
132
132
|
decimal_value.present? ? decimal_value.to_s.to_d : decimal_value
|
|
133
133
|
when :integer
|
|
134
|
-
value.
|
|
134
|
+
int_value = value.presence
|
|
135
|
+
int_value ||= 0 unless nullable
|
|
136
|
+
int_value.present? ? int_value.to_i : int_value
|
|
135
137
|
when :boolean
|
|
136
138
|
if value.is_a?(FalseClass) ||
|
|
137
139
|
value.nil? ||
|
|
@@ -162,6 +164,17 @@ module Spree::Preferences::Preferable
|
|
|
162
164
|
else
|
|
163
165
|
value.class.ancestors.include?(Hash) ? value : {}
|
|
164
166
|
end
|
|
167
|
+
when :datetime
|
|
168
|
+
return nil if value.blank?
|
|
169
|
+
|
|
170
|
+
case value
|
|
171
|
+
when Time, Date, DateTime, ActiveSupport::TimeWithZone
|
|
172
|
+
value
|
|
173
|
+
when String
|
|
174
|
+
Time.zone.parse(value)
|
|
175
|
+
else
|
|
176
|
+
value.to_time
|
|
177
|
+
end
|
|
165
178
|
else
|
|
166
179
|
value
|
|
167
180
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Pricing
|
|
3
|
+
class Context
|
|
4
|
+
attr_reader :variant, :currency, :store, :zone, :user, :quantity, :date, :order
|
|
5
|
+
|
|
6
|
+
# Initializes the context
|
|
7
|
+
# @param variant [Spree::Variant]
|
|
8
|
+
# @param currency [String]
|
|
9
|
+
# @param store [Spree::Store]
|
|
10
|
+
# @param zone [Spree::Zone]
|
|
11
|
+
# @param user [Spree::User]
|
|
12
|
+
# @param quantity [Integer]
|
|
13
|
+
# @param date [Time]
|
|
14
|
+
# @param order [Spree::Order]
|
|
15
|
+
def initialize(variant: nil, currency:, store: nil, zone: nil, user: nil, quantity: nil, date: nil, order: nil)
|
|
16
|
+
@variant = variant
|
|
17
|
+
@currency = currency
|
|
18
|
+
@store = store || Spree::Current.store
|
|
19
|
+
@zone = zone || Spree::Current.zone
|
|
20
|
+
@user = user
|
|
21
|
+
@quantity = quantity
|
|
22
|
+
@date = date || Time.current
|
|
23
|
+
@order = order
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns a new context from a variant and currency
|
|
27
|
+
# @param variant [Spree::Variant]
|
|
28
|
+
# @param currency [String]
|
|
29
|
+
# @return [Spree::Pricing::Context]
|
|
30
|
+
def self.from_currency(variant, currency)
|
|
31
|
+
new(variant: variant, currency: currency)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.from_order(variant, order, quantity: nil)
|
|
35
|
+
new(
|
|
36
|
+
variant: variant,
|
|
37
|
+
currency: order.currency,
|
|
38
|
+
store: order.store,
|
|
39
|
+
zone: order.tax_zone || order.store.checkout_zone,
|
|
40
|
+
user: order.user,
|
|
41
|
+
quantity: quantity || order.line_items.find_by(variant: variant)&.quantity,
|
|
42
|
+
order: order
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns the cache key for the context
|
|
47
|
+
# @return [String]
|
|
48
|
+
def cache_key
|
|
49
|
+
[
|
|
50
|
+
'spree',
|
|
51
|
+
'pricing',
|
|
52
|
+
variant.id,
|
|
53
|
+
currency,
|
|
54
|
+
store&.id,
|
|
55
|
+
zone&.id,
|
|
56
|
+
user&.id,
|
|
57
|
+
quantity,
|
|
58
|
+
date&.to_i
|
|
59
|
+
].compact.join('/')
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Pricing
|
|
3
|
+
class Resolver
|
|
4
|
+
attr_reader :context
|
|
5
|
+
|
|
6
|
+
# Initializes the resolver
|
|
7
|
+
# @param context [Spree::Pricing::Context]
|
|
8
|
+
def initialize(context)
|
|
9
|
+
@context = context
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Returns the best price for the variant
|
|
13
|
+
# @return [Spree::Price]
|
|
14
|
+
def resolve
|
|
15
|
+
Rails.cache.fetch(cache_key, expires_in: 15.minutes) do
|
|
16
|
+
find_best_price
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
# Returns the best price for the variant
|
|
23
|
+
# @return [Spree::Price]
|
|
24
|
+
def find_best_price
|
|
25
|
+
# Try to find a price from applicable price lists first
|
|
26
|
+
price_from_list = find_price_from_lists
|
|
27
|
+
return price_from_list if price_from_list
|
|
28
|
+
|
|
29
|
+
# Fall back to base price (no price_list_id)
|
|
30
|
+
find_base_price
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Returns the price from applicable price lists
|
|
34
|
+
# @return [Spree::Price]
|
|
35
|
+
def find_price_from_lists
|
|
36
|
+
applicable_price_lists.each do |price_list|
|
|
37
|
+
price = find_price_for_list(price_list)
|
|
38
|
+
return price if price
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the price lists that are applicable to the context
|
|
45
|
+
# @return [Array<Spree::PriceList>]
|
|
46
|
+
def applicable_price_lists
|
|
47
|
+
@applicable_price_lists ||= price_lists_for_context.select { |list| list.applicable?(context) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns the price lists for the context's store
|
|
51
|
+
# Uses Spree::Current.price_lists if the context matches, otherwise fetches directly
|
|
52
|
+
# @return [ActiveRecord::Relation<Spree::PriceList>]
|
|
53
|
+
def price_lists_for_context
|
|
54
|
+
if context.store == Spree::Current.store && context.currency == Spree::Current.currency
|
|
55
|
+
Spree::Current.price_lists
|
|
56
|
+
else
|
|
57
|
+
Spree::PriceList.for_context(context)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns the price for a given price list
|
|
62
|
+
# @param price_list [Spree::PriceList]
|
|
63
|
+
# @return [Spree::Price]
|
|
64
|
+
def find_price_for_list(price_list)
|
|
65
|
+
currency = context.currency&.upcase
|
|
66
|
+
|
|
67
|
+
if prices.loaded?
|
|
68
|
+
prices.detect do |p|
|
|
69
|
+
p.currency == currency &&
|
|
70
|
+
p.price_list_id == price_list.id &&
|
|
71
|
+
p.amount.present? &&
|
|
72
|
+
!p.amount.zero?
|
|
73
|
+
end
|
|
74
|
+
else
|
|
75
|
+
context.variant.prices
|
|
76
|
+
.with_currency(currency)
|
|
77
|
+
.where(price_list_id: price_list.id)
|
|
78
|
+
.non_zero
|
|
79
|
+
.first
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns the base price for the variant in the current currency
|
|
84
|
+
# @return [Spree::Price]
|
|
85
|
+
def find_base_price
|
|
86
|
+
currency = context.currency&.upcase
|
|
87
|
+
|
|
88
|
+
price = if prices.loaded?
|
|
89
|
+
prices.detect do |p|
|
|
90
|
+
p.currency == currency &&
|
|
91
|
+
p.price_list_id.nil? &&
|
|
92
|
+
p.amount.present?
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
context.variant.prices
|
|
96
|
+
.with_currency(currency)
|
|
97
|
+
.where(price_list_id: nil)
|
|
98
|
+
.where.not(amount: nil)
|
|
99
|
+
.first
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
price || build_empty_price
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Returns the prices for the variant
|
|
106
|
+
# @return [ActiveRecord::Relation<Spree::Price>]
|
|
107
|
+
def prices
|
|
108
|
+
context.variant.prices
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Builds an empty price for the variant
|
|
112
|
+
# @return [Spree::Price]
|
|
113
|
+
def build_empty_price
|
|
114
|
+
context.variant.prices.build(
|
|
115
|
+
variant: context.variant,
|
|
116
|
+
currency: context.currency,
|
|
117
|
+
amount: nil,
|
|
118
|
+
price_list_id: nil
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Returns the cache key for the resolver
|
|
123
|
+
# @return [String]
|
|
124
|
+
def cache_key
|
|
125
|
+
"#{context.cache_key}/resolved_price"
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
attr_accessor :properties, :current_user, :current_currency, :current_store, :taxon
|
|
6
6
|
|
|
7
7
|
def initialize(params)
|
|
8
|
-
Spree::Deprecation.warn("Spree::Core::Search::Base is deprecated and will be removed in Spree
|
|
8
|
+
Spree::Deprecation.warn("Spree::Core::Search::Base is deprecated and will be removed in Spree 5.5. Please use `Spree::Products::Find` finder instead.")
|
|
9
9
|
|
|
10
10
|
@properties = {}
|
|
11
11
|
@current_store = params[:current_store] || Spree::Store.default
|
|
@@ -2,7 +2,7 @@ module Spree
|
|
|
2
2
|
module Core
|
|
3
3
|
module TokenGenerator
|
|
4
4
|
def generate_token(model_class = Spree::Order)
|
|
5
|
-
Spree::Deprecation.warn('generate_token is deprecated and will be removed in Spree
|
|
5
|
+
Spree::Deprecation.warn('generate_token is deprecated and will be removed in Spree 5.5. Please use Rails secure token generator: https://api.rubyonrails.org/classes/ActiveRecord/SecureToken/ClassMethods.html')
|
|
6
6
|
loop do
|
|
7
7
|
token = "#{random_token}#{unique_ending}"
|
|
8
8
|
break token unless model_class.exists?(token: token)
|