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,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
class Shipment < Spree.base_class
|
|
5
|
+
# Publishes custom shipment events beyond basic lifecycle events.
|
|
6
|
+
#
|
|
7
|
+
# Events:
|
|
8
|
+
# - shipment.shipped: Shipment was shipped
|
|
9
|
+
# - order.shipped: All order shipments are shipped
|
|
10
|
+
# - shipment.canceled: Shipment was canceled
|
|
11
|
+
# - shipment.resumed: Shipment was resumed from canceled state
|
|
12
|
+
#
|
|
13
|
+
# NOTE: These methods are called from the state machine's after_transition callbacks
|
|
14
|
+
# defined in the Shipment model, not via ActiveRecord callbacks.
|
|
15
|
+
#
|
|
16
|
+
module CustomEvents
|
|
17
|
+
extend ActiveSupport::Concern
|
|
18
|
+
|
|
19
|
+
def publish_shipment_shipped_event
|
|
20
|
+
return unless Spree::Events.enabled?
|
|
21
|
+
|
|
22
|
+
publish_event('shipment.shipped')
|
|
23
|
+
# Force reload of shipments association to see the new state
|
|
24
|
+
order.shipments.reset
|
|
25
|
+
publish_order_shipped_event if order.fully_shipped?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def publish_shipment_canceled_event
|
|
29
|
+
return unless Spree::Events.enabled?
|
|
30
|
+
|
|
31
|
+
publish_event('shipment.canceled')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def publish_shipment_resumed_event
|
|
35
|
+
return unless Spree::Events.enabled?
|
|
36
|
+
|
|
37
|
+
publish_event('shipment.resumed')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def publish_order_shipped_event
|
|
43
|
+
order.publish_event('order.shipped')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -15,6 +15,9 @@ module Spree
|
|
|
15
15
|
end
|
|
16
16
|
include Spree::Shipment::Emails
|
|
17
17
|
include Spree::Shipment::Webhooks
|
|
18
|
+
include Spree::Shipment::CustomEvents
|
|
19
|
+
|
|
20
|
+
publishes_lifecycle_events
|
|
18
21
|
|
|
19
22
|
with_options inverse_of: :shipments do
|
|
20
23
|
belongs_to :address, class_name: 'Spree::Address'
|
|
@@ -82,12 +85,12 @@ module Spree
|
|
|
82
85
|
event :ship do
|
|
83
86
|
transition from: %i(ready canceled), to: :shipped
|
|
84
87
|
end
|
|
85
|
-
after_transition to: :shipped, do: [:after_ship, :send_shipment_shipped_webhook]
|
|
88
|
+
after_transition to: :shipped, do: [:after_ship, :send_shipment_shipped_webhook, :publish_shipment_shipped_event]
|
|
86
89
|
|
|
87
90
|
event :cancel do
|
|
88
91
|
transition to: :canceled, from: %i(pending ready)
|
|
89
92
|
end
|
|
90
|
-
after_transition to: :canceled, do: :after_cancel
|
|
93
|
+
after_transition to: :canceled, do: [:after_cancel, :publish_shipment_canceled_event]
|
|
91
94
|
|
|
92
95
|
event :resume do
|
|
93
96
|
transition from: :canceled, to: :ready, if: lambda { |shipment|
|
|
@@ -95,7 +98,7 @@ module Spree
|
|
|
95
98
|
}
|
|
96
99
|
transition from: :canceled, to: :pending
|
|
97
100
|
end
|
|
98
|
-
after_transition from: :canceled, to: %i(pending ready shipped), do: :after_resume
|
|
101
|
+
after_transition from: :canceled, to: %i(pending ready shipped), do: [:after_resume, :publish_shipment_resumed_event]
|
|
99
102
|
|
|
100
103
|
after_transition do |shipment, transition|
|
|
101
104
|
shipment.state_changes.create!(
|
|
@@ -112,7 +115,7 @@ module Spree
|
|
|
112
115
|
money_methods :cost, :discounted_cost, :final_price, :item_cost, :additional_tax_total, :included_tax_total, :tax_total
|
|
113
116
|
alias display_amount display_cost
|
|
114
117
|
|
|
115
|
-
|
|
118
|
+
normalizes :tracking, with: ->(value) { value&.to_s&.squish&.presence }
|
|
116
119
|
|
|
117
120
|
# Returns the shipment number and shipping method name
|
|
118
121
|
#
|
|
@@ -209,7 +212,8 @@ module Spree
|
|
|
209
212
|
#
|
|
210
213
|
# @return [Boolean]
|
|
211
214
|
def with_free_shipping_promotion?
|
|
212
|
-
adjustments.promotion.
|
|
215
|
+
adjustments.promotion.joins("INNER JOIN #{Spree::PromotionAction.table_name} ON #{Spree::PromotionAction.table_name}.id = #{Spree::Adjustment.table_name}.source_id").
|
|
216
|
+
where("#{Spree::PromotionAction.table_name}.type = 'Spree::Promotion::Actions::FreeShipping'").exists?
|
|
213
217
|
end
|
|
214
218
|
|
|
215
219
|
def finalize!
|
|
@@ -454,6 +458,9 @@ module Spree
|
|
|
454
458
|
ShipmentHandler.factory(self).perform
|
|
455
459
|
end
|
|
456
460
|
|
|
461
|
+
# publish_shipment_shipped_event, publish_shipment_canceled_event, and
|
|
462
|
+
# publish_shipment_resumed_event are defined in Spree::Shipment::CustomEvents
|
|
463
|
+
|
|
457
464
|
def can_get_rates?
|
|
458
465
|
return true unless order.requires_ship_address?
|
|
459
466
|
|
|
@@ -6,6 +6,8 @@ module Spree
|
|
|
6
6
|
include Spree::Metadata
|
|
7
7
|
include Spree::StockItem::Webhooks
|
|
8
8
|
|
|
9
|
+
publishes_lifecycle_events
|
|
10
|
+
|
|
9
11
|
with_options inverse_of: :stock_items do
|
|
10
12
|
belongs_to :stock_location, class_name: 'Spree::StockLocation'
|
|
11
13
|
belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant'
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class StockLocation < Spree.base_class
|
|
3
3
|
include Spree::UniqueName
|
|
4
|
-
if defined?(Spree::Webhooks::HasWebhooks)
|
|
5
|
-
include Spree::Webhooks::HasWebhooks
|
|
6
|
-
end
|
|
7
4
|
if defined?(Spree::Security::StockLocations)
|
|
8
5
|
include Spree::Security::StockLocations
|
|
9
6
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
class StockMovement < Spree.base_class
|
|
5
|
+
# Publishes custom stock events when stock levels change.
|
|
6
|
+
#
|
|
7
|
+
# Events:
|
|
8
|
+
# - product.out_of_stock: Product has no stock left for any variant
|
|
9
|
+
# - product.back_in_stock: Product was out of stock and now has stock again
|
|
10
|
+
#
|
|
11
|
+
module CustomEvents
|
|
12
|
+
extend ActiveSupport::Concern
|
|
13
|
+
|
|
14
|
+
included do
|
|
15
|
+
around_save :track_stock_changes_for_events
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def track_stock_changes_for_events
|
|
21
|
+
return yield unless Spree::Events.enabled?
|
|
22
|
+
|
|
23
|
+
the_product = product
|
|
24
|
+
product_was_in_stock = the_product.any_variant_in_stock_or_backorderable?
|
|
25
|
+
|
|
26
|
+
yield
|
|
27
|
+
|
|
28
|
+
# Reload to get fresh stock data
|
|
29
|
+
the_product.reload
|
|
30
|
+
product_now_in_stock = the_product.any_variant_in_stock_or_backorderable?
|
|
31
|
+
|
|
32
|
+
if product_was_in_stock && !product_now_in_stock
|
|
33
|
+
the_product.publish_event('product.out_of_stock')
|
|
34
|
+
elsif !product_was_in_stock && product_now_in_stock
|
|
35
|
+
the_product.publish_event('product.back_in_stock')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def product
|
|
40
|
+
stock_item.variant.product
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -6,6 +6,9 @@ module Spree
|
|
|
6
6
|
}.freeze
|
|
7
7
|
|
|
8
8
|
include Spree::StockMovement::Webhooks
|
|
9
|
+
include Spree::StockMovement::CustomEvents
|
|
10
|
+
|
|
11
|
+
publishes_lifecycle_events
|
|
9
12
|
|
|
10
13
|
belongs_to :stock_item, class_name: 'Spree::StockItem', inverse_of: :stock_movements
|
|
11
14
|
belongs_to :originator, polymorphic: true
|
|
@@ -5,9 +5,8 @@ module Spree
|
|
|
5
5
|
include Spree::NumberAsParam
|
|
6
6
|
include Spree::Metafields
|
|
7
7
|
include Spree::Metadata
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
end
|
|
8
|
+
|
|
9
|
+
publishes_lifecycle_events
|
|
11
10
|
|
|
12
11
|
has_many :stock_movements, as: :originator
|
|
13
12
|
accepts_nested_attributes_for :stock_movements, reject_if: proc { |attributes|
|
data/app/models/spree/store.rb
CHANGED
|
@@ -12,10 +12,8 @@ module Spree
|
|
|
12
12
|
include Spree::Metadata
|
|
13
13
|
include Spree::Stores::Setup
|
|
14
14
|
include Spree::Stores::Socials
|
|
15
|
-
include Spree::Webhooks::HasWebhooks if defined?(Spree::Webhooks::HasWebhooks)
|
|
16
15
|
include Spree::Security::Stores if defined?(Spree::Security::Stores)
|
|
17
16
|
include Spree::UserManagement
|
|
18
|
-
include Spree::HasPageLinks
|
|
19
17
|
|
|
20
18
|
#
|
|
21
19
|
# Magic methods
|
|
@@ -115,23 +113,10 @@ module Spree
|
|
|
115
113
|
|
|
116
114
|
has_many :policies, class_name: 'Spree::Policy', dependent: :destroy, as: :owner
|
|
117
115
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
has_many :
|
|
122
|
-
has_many :theme_previews,
|
|
123
|
-
-> { only_previews },
|
|
124
|
-
class_name: 'Spree::Theme',
|
|
125
|
-
through: :themes,
|
|
126
|
-
source: :previews,
|
|
127
|
-
inverse_of: :store,
|
|
128
|
-
dependent: :destroy
|
|
129
|
-
has_one :default_theme, -> { without_previews.where(default: true) }, class_name: 'Spree::Theme', inverse_of: :store
|
|
130
|
-
alias theme default_theme
|
|
131
|
-
has_many :theme_pages, class_name: 'Spree::Page', through: :themes, source: :pages
|
|
132
|
-
has_many :theme_page_previews, class_name: 'Spree::Page', through: :theme_pages, source: :previews
|
|
133
|
-
has_many :pages, -> { without_previews.custom }, class_name: 'Spree::Pages::Custom', dependent: :destroy, as: :pageable
|
|
134
|
-
has_many :page_previews, class_name: 'Spree::Pages::Custom', through: :pages, as: :pageable, source: :previews
|
|
116
|
+
has_many :webhook_endpoints, class_name: 'Spree::WebhookEndpoint', dependent: :destroy, inverse_of: :store
|
|
117
|
+
has_many :webhook_deliveries, through: :webhook_endpoints, class_name: 'Spree::WebhookDelivery'
|
|
118
|
+
|
|
119
|
+
has_many :customer_groups, class_name: 'Spree::CustomerGroup', dependent: :destroy, inverse_of: :store
|
|
135
120
|
|
|
136
121
|
#
|
|
137
122
|
# ActionText
|
|
@@ -189,7 +174,6 @@ module Spree
|
|
|
189
174
|
after_create :ensure_default_post_categories_are_created
|
|
190
175
|
after_create :import_products_from_store, if: -> { import_products_from_store_id.present? }
|
|
191
176
|
after_create :import_payment_methods_from_store, if: -> { import_payment_methods_from_store_id.present? }
|
|
192
|
-
after_create :create_default_theme
|
|
193
177
|
after_create :create_default_policies
|
|
194
178
|
before_destroy :validate_not_last, unless: :skip_validate_not_last
|
|
195
179
|
before_destroy :pass_default_flag_to_other_store
|
|
@@ -347,12 +331,6 @@ module Spree
|
|
|
347
331
|
end
|
|
348
332
|
end
|
|
349
333
|
|
|
350
|
-
def checkout_zone_or_default
|
|
351
|
-
Spree::Deprecation.warn('Store#checkout_zone_or_default is deprecated and will be removed in Spree 5')
|
|
352
|
-
|
|
353
|
-
@checkout_zone_or_default ||= checkout_zone || Spree::Zone.default_checkout_zone
|
|
354
|
-
end
|
|
355
|
-
|
|
356
334
|
def supported_shipping_zones
|
|
357
335
|
@supported_shipping_zones ||= if checkout_zone.present?
|
|
358
336
|
[checkout_zone]
|
|
@@ -373,7 +351,7 @@ module Spree
|
|
|
373
351
|
end
|
|
374
352
|
|
|
375
353
|
def admin_users
|
|
376
|
-
Spree::Deprecation.warn('Store#admin_users is deprecated and will be removed in Spree
|
|
354
|
+
Spree::Deprecation.warn('Store#admin_users is deprecated and will be removed in Spree 5.5. Please use Store#users instead.')
|
|
377
355
|
|
|
378
356
|
users
|
|
379
357
|
end
|
|
@@ -420,19 +398,12 @@ module Spree
|
|
|
420
398
|
|
|
421
399
|
%w[customer_terms_of_service customer_privacy_policy customer_returns_policy customer_shipping_policy].each do |policy_method|
|
|
422
400
|
define_method policy_method do
|
|
423
|
-
Spree::Deprecation.warn("Store##{policy_method} is deprecated and will be removed in Spree
|
|
401
|
+
Spree::Deprecation.warn("Store##{policy_method} is deprecated and will be removed in Spree 5.5. Please use Store#policies instead.")
|
|
424
402
|
|
|
425
403
|
ActionText::RichText.find_by(name: policy_method, record: self)
|
|
426
404
|
end
|
|
427
405
|
end
|
|
428
406
|
|
|
429
|
-
# Returns all active webhooks subscribers for the store
|
|
430
|
-
#
|
|
431
|
-
# @return [Array<Spree::Webhooks::Subscriber>]
|
|
432
|
-
def active_webhooks_subscribers
|
|
433
|
-
@active_webhooks_subscribers ||= Spree::Webhooks::Subscriber.active
|
|
434
|
-
end
|
|
435
|
-
|
|
436
407
|
private
|
|
437
408
|
|
|
438
409
|
def countries_available_for_checkout_cache_key
|
|
@@ -496,69 +467,77 @@ module Spree
|
|
|
496
467
|
end
|
|
497
468
|
|
|
498
469
|
def ensure_default_taxonomies_are_created
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
470
|
+
Spree::Events.disable do
|
|
471
|
+
[
|
|
472
|
+
translate_with_store_locale_fallback('spree.taxonomy_categories_name'),
|
|
473
|
+
translate_with_store_locale_fallback('spree.taxonomy_brands_name'),
|
|
474
|
+
translate_with_store_locale_fallback('spree.taxonomy_collections_name')
|
|
475
|
+
].each do |taxonomy_name|
|
|
476
|
+
# Manual exists?/create to work around Mobility bug with find_or_create_by
|
|
477
|
+
next if taxonomies.with_matching_name(taxonomy_name).exists?
|
|
478
|
+
|
|
479
|
+
taxonomies.create(name: taxonomy_name)
|
|
480
|
+
end
|
|
508
481
|
end
|
|
509
482
|
end
|
|
510
483
|
|
|
511
484
|
def ensure_default_automatic_taxons
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
taxon_scope.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
485
|
+
Spree::Events.disable do
|
|
486
|
+
# Use Mobility-safe lookup for taxonomy
|
|
487
|
+
collections_taxonomy = taxonomies.with_matching_name(translate_with_store_locale_fallback('spree.taxonomy_collections_name')).first
|
|
488
|
+
return unless collections_taxonomy.present?
|
|
489
|
+
|
|
490
|
+
automatic_taxons_config = [
|
|
491
|
+
{ name: translate_with_store_locale_fallback('spree.automatic_taxon_names.on_sale'), rule_type: 'Spree::TaxonRules::Sale', rule_value: 'true' },
|
|
492
|
+
{ name: translate_with_store_locale_fallback('spree.automatic_taxon_names.new_arrivals'), rule_type: 'Spree::TaxonRules::AvailableOn', rule_value: 30 }
|
|
493
|
+
]
|
|
494
|
+
|
|
495
|
+
automatic_taxons_config.map do |config|
|
|
496
|
+
# Manual exists?/create to work around Mobility bug with first_or_create
|
|
497
|
+
taxon_scope = collections_taxonomy.taxons.automatic.with_matching_name(config[:name])
|
|
498
|
+
|
|
499
|
+
if taxon_scope.exists?
|
|
500
|
+
taxon_scope.first
|
|
501
|
+
else
|
|
502
|
+
collections_taxonomy.taxons.create!(
|
|
503
|
+
name: config[:name],
|
|
504
|
+
automatic: true,
|
|
505
|
+
parent: collections_taxonomy.root,
|
|
506
|
+
taxon_rules: [TaxonRule.new(type: config[:rule_type], value: config[:rule_value])]
|
|
507
|
+
)
|
|
508
|
+
end
|
|
534
509
|
end
|
|
535
510
|
end
|
|
536
511
|
end
|
|
537
512
|
|
|
538
513
|
def ensure_default_post_categories_are_created
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
514
|
+
Spree::Events.disable do
|
|
515
|
+
[
|
|
516
|
+
translate_with_store_locale_fallback('spree.default_post_categories.resources'),
|
|
517
|
+
translate_with_store_locale_fallback('spree.default_post_categories.articles'),
|
|
518
|
+
translate_with_store_locale_fallback('spree.default_post_categories.news')
|
|
519
|
+
].each do |category_title|
|
|
520
|
+
# Use exists?/create pattern for safety
|
|
521
|
+
next if post_categories.where(title: category_title).exists?
|
|
522
|
+
|
|
523
|
+
post_categories.create(title: category_title)
|
|
524
|
+
end
|
|
548
525
|
end
|
|
549
526
|
end
|
|
550
527
|
|
|
551
528
|
def create_default_policies
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
529
|
+
Spree::Events.disable do
|
|
530
|
+
[
|
|
531
|
+
translate_with_store_locale_fallback('spree.terms_of_service'),
|
|
532
|
+
translate_with_store_locale_fallback('spree.privacy_policy'),
|
|
533
|
+
translate_with_store_locale_fallback('spree.returns_policy'),
|
|
534
|
+
translate_with_store_locale_fallback('spree.shipping_policy')
|
|
535
|
+
].each do |policy_name|
|
|
536
|
+
# Manual exists?/create to work around Mobility bug with find_or_create_by
|
|
537
|
+
next if policies.with_matching_name(policy_name).exists?
|
|
538
|
+
|
|
539
|
+
policies.create(name: policy_name)
|
|
540
|
+
end
|
|
562
541
|
end
|
|
563
542
|
end
|
|
564
543
|
|
|
@@ -605,12 +584,5 @@ module Spree
|
|
|
605
584
|
|
|
606
585
|
self.url = [code, Spree.root_domain].join('.')
|
|
607
586
|
end
|
|
608
|
-
|
|
609
|
-
def create_default_theme
|
|
610
|
-
themes.find_or_initialize_by(default: true) do |theme|
|
|
611
|
-
theme.name = Spree.t(:default_theme_name)
|
|
612
|
-
theme.save!
|
|
613
|
-
end
|
|
614
|
-
end
|
|
615
587
|
end
|
|
616
588
|
end
|
|
@@ -3,9 +3,8 @@ module Spree
|
|
|
3
3
|
include Spree::SingleStoreResource
|
|
4
4
|
include Spree::Metafields
|
|
5
5
|
include Spree::Metadata
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
end
|
|
6
|
+
|
|
7
|
+
publishes_lifecycle_events
|
|
9
8
|
|
|
10
9
|
acts_as_paranoid
|
|
11
10
|
|
|
@@ -186,7 +185,7 @@ module Spree
|
|
|
186
185
|
|
|
187
186
|
class << self
|
|
188
187
|
def default_created_by
|
|
189
|
-
Spree::Deprecation.warn('StoreCredit#default_created_by is deprecated and will be removed in Spree
|
|
188
|
+
Spree::Deprecation.warn('StoreCredit#default_created_by is deprecated and will be removed in Spree 5.5. Please use store.users.first instead.')
|
|
190
189
|
|
|
191
190
|
Spree::Store.current.users.first
|
|
192
191
|
end
|
|
@@ -7,5 +7,19 @@ module Spree
|
|
|
7
7
|
|
|
8
8
|
validates :store, :product, presence: true
|
|
9
9
|
validates :store_id, uniqueness: { scope: :product_id }
|
|
10
|
+
|
|
11
|
+
def refresh_metrics!
|
|
12
|
+
completed_order_ids = product.completed_orders.where(store_id: store_id).select(:id)
|
|
13
|
+
variant_ids = product.variants_including_master.ids
|
|
14
|
+
|
|
15
|
+
line_items = Spree::LineItem.joins(:order)
|
|
16
|
+
.where(spree_orders: { id: completed_order_ids })
|
|
17
|
+
.where(variant_id: variant_ids)
|
|
18
|
+
|
|
19
|
+
update!(
|
|
20
|
+
units_sold_count: line_items.sum(:quantity),
|
|
21
|
+
revenue: line_items.sum(:pre_tax_amount)
|
|
22
|
+
)
|
|
23
|
+
end
|
|
10
24
|
end
|
|
11
25
|
end
|