solidus_core 4.1.6 → 4.5.1
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/assets/images/logo/solidus.svg +18 -1
- data/app/assets/images/logo/solidus_logo.png +0 -0
- data/app/helpers/spree/base_helper.rb +2 -2
- data/app/helpers/spree/core/controller_helpers/auth.rb +66 -0
- data/app/helpers/spree/core/controller_helpers/common.rb +82 -0
- data/app/helpers/spree/core/controller_helpers/order.rb +86 -0
- data/app/helpers/spree/core/controller_helpers/payment_parameters.rb +165 -0
- data/app/helpers/spree/core/controller_helpers/pricing.rb +19 -0
- data/app/helpers/spree/core/controller_helpers/search.rb +16 -0
- data/app/helpers/spree/core/controller_helpers/store.rb +19 -0
- data/app/helpers/spree/core/controller_helpers/strong_parameters.rb +74 -0
- data/app/mailers/spree/base_mailer.rb +1 -1
- data/app/mailers/spree/carton_mailer.rb +1 -1
- data/app/mailers/spree/order_mailer.rb +3 -3
- data/app/mailers/spree/reimbursement_mailer.rb +1 -1
- data/app/models/concerns/spree/active_storage_adapter/normalization.rb +1 -1
- data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
- data/app/models/concerns/spree/display_money.rb +1 -1
- data/app/models/concerns/spree/metadata.rb +64 -0
- data/app/models/concerns/spree/named_type.rb +2 -0
- data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
- data/app/models/concerns/spree/user_address_book.rb +8 -9
- data/app/models/concerns/spree/user_methods.rb +3 -3
- data/app/models/spree/address.rb +10 -8
- data/app/models/spree/adjustment.rb +15 -65
- data/app/models/spree/adjustment_reason.rb +2 -0
- data/app/models/spree/calculator/returns/default_refund_amount.rb +1 -1
- data/app/models/spree/carton.rb +2 -2
- data/app/models/spree/core/state_machines/inventory_unit.rb +42 -0
- data/app/models/spree/core/state_machines/order/class_methods.rb +217 -0
- data/app/models/spree/core/state_machines/order.rb +42 -0
- data/app/models/spree/core/state_machines/payment.rb +61 -0
- data/app/models/spree/core/state_machines/reimbursement.rb +33 -0
- data/app/models/spree/core/state_machines/return_authorization.rb +32 -0
- data/app/models/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
- data/app/models/spree/core/state_machines/return_item/reception_status.rb +42 -0
- data/app/models/spree/core/state_machines/shipment.rb +58 -0
- data/app/models/spree/credit_card.rb +12 -9
- data/app/models/spree/customer_return.rb +2 -0
- data/app/models/spree/deprecated_configurable_class.rb +40 -0
- data/app/models/spree/fulfilment_changer.rb +4 -4
- data/app/models/spree/inventory_unit.rb +2 -2
- data/app/models/spree/item_total.rb +28 -0
- data/app/models/spree/legacy_user.rb +1 -0
- data/app/models/spree/line_item.rb +22 -4
- data/app/models/spree/money.rb +120 -0
- data/app/models/spree/null_promotion_adjuster.rb +13 -0
- data/app/models/spree/null_promotion_advertiser.rb +9 -0
- data/app/models/spree/null_promotion_finder.rb +9 -0
- data/app/models/spree/null_promotion_handler.rb +44 -0
- data/app/models/spree/option_value.rb +1 -0
- data/app/models/spree/order.rb +54 -36
- data/app/models/spree/order_cancellations.rb +8 -8
- data/app/models/spree/order_inventory.rb +6 -4
- data/app/models/spree/order_merger.rb +1 -1
- data/app/models/spree/order_mutex.rb +2 -2
- data/app/models/spree/order_shipping.rb +9 -9
- data/app/models/spree/order_taxation.rb +1 -0
- data/app/models/spree/order_updater.rb +19 -40
- data/app/models/spree/payment/processing.rb +2 -2
- data/app/models/spree/payment.rb +3 -2
- data/app/models/spree/payment_create.rb +1 -1
- data/app/models/spree/payment_method/bogus_credit_card.rb +14 -9
- data/app/models/spree/payment_method/simple_bogus_credit_card.rb +12 -6
- data/app/models/spree/payment_method/store_credit.rb +1 -1
- data/app/models/spree/payment_method.rb +3 -1
- data/app/models/spree/payment_source.rb +5 -1
- data/app/models/spree/permission_set.rb +11 -0
- data/app/models/spree/permission_sets/base.rb +45 -0
- data/app/models/spree/permission_sets/configuration_display.rb +53 -0
- data/app/models/spree/permission_sets/configuration_management.rb +52 -0
- data/app/models/spree/permission_sets/dashboard_display.rb +28 -0
- data/app/models/spree/permission_sets/default_customer.rb +83 -0
- data/app/models/spree/permission_sets/order_display.rb +50 -0
- data/app/models/spree/permission_sets/order_management.rb +50 -0
- data/app/models/spree/permission_sets/product_display.rb +43 -0
- data/app/models/spree/permission_sets/product_management.rb +47 -0
- data/app/models/spree/permission_sets/restricted_stock_display.rb +33 -0
- data/app/models/spree/permission_sets/restricted_stock_management.rb +33 -0
- data/app/models/spree/permission_sets/stock_display.rb +26 -0
- data/app/models/spree/permission_sets/stock_management.rb +26 -0
- data/app/models/spree/permission_sets/super_user.rb +26 -0
- data/app/models/spree/permission_sets/user_display.rb +27 -0
- data/app/models/spree/permission_sets/user_management.rb +44 -0
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/product.rb +13 -9
- data/app/models/spree/refund.rb +3 -1
- data/app/models/spree/refund_reason.rb +6 -1
- data/app/models/spree/reimbursement.rb +4 -4
- data/app/models/spree/reimbursement_performer.rb +3 -3
- data/app/models/spree/reimbursement_tax_calculator.rb +2 -2
- data/app/models/spree/reimbursement_type/credit.rb +1 -1
- data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +6 -6
- data/app/models/spree/reimbursement_type/store_credit.rb +1 -1
- data/app/models/spree/reimbursement_type.rb +6 -1
- data/app/models/spree/return_authorization.rb +2 -0
- data/app/models/spree/return_item.rb +10 -10
- data/app/models/spree/return_reason.rb +6 -1
- data/app/models/spree/role.rb +3 -1
- data/app/models/spree/role_permission.rb +8 -0
- data/app/models/spree/shipment.rb +9 -7
- data/app/models/spree/shipping_category.rb +2 -0
- data/app/models/spree/shipping_rate.rb +2 -3
- data/app/models/spree/{order_contents.rb → simple_order_contents.rb} +8 -12
- 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/package.rb +2 -2
- data/app/models/spree/stock/simple_coordinator.rb +36 -22
- data/app/models/spree/stock_item.rb +1 -0
- data/app/models/spree/stock_location.rb +5 -5
- data/app/models/spree/store.rb +3 -1
- data/app/models/spree/store_credit.rb +17 -15
- data/app/models/spree/store_credit_event.rb +4 -3
- data/app/models/spree/store_credit_reason.rb +6 -1
- data/app/models/spree/store_selector/by_server_name.rb +1 -1
- data/app/models/spree/tax/tax_helpers.rb +12 -1
- data/app/models/spree/tax_calculator/default.rb +3 -3
- data/app/models/spree/tax_calculator/shipping_rate.rb +1 -1
- data/app/models/spree/tax_category.rb +3 -1
- data/app/models/spree/tax_rate.rb +7 -3
- data/app/models/spree/taxon.rb +22 -2
- data/app/models/spree/taxon_brand_selector.rb +22 -0
- data/app/models/spree/taxonomy.rb +2 -2
- data/app/models/spree/unauthorized_redirect_handler.rb +24 -0
- data/app/models/spree/unit_cancel.rb +1 -2
- data/app/models/spree/user_address.rb +9 -3
- data/app/models/spree/variant/scopes.rb +4 -0
- data/app/models/spree/variant/vat_price_generator.rb +1 -1
- data/app/models/spree/variant.rb +21 -8
- data/app/models/spree/wallet.rb +2 -2
- data/app/views/spree/order_mailer/cancel_email.html.erb +1 -1
- data/app/views/spree/order_mailer/cancel_email.text.erb +1 -1
- data/app/views/spree/order_mailer/confirm_email.html.erb +5 -5
- data/app/views/spree/order_mailer/confirm_email.text.erb +5 -5
- data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +0 -1
- data/config/locales/en.yml +33 -90
- data/db/default/spree/permission_sets.rb +10 -0
- data/db/default/spree/return_reasons.rb +3 -1
- data/db/default/spree/states.rb +1 -1
- data/db/migrate/20160101010000_solidus_one_four.rb +0 -127
- data/db/migrate/20220419170826_remove_archived_user_addresses.rb +12 -0
- data/db/migrate/20230427095534_drop_deprecated_address_id_from_shipments.rb +1 -1
- data/db/migrate/20240821173254_create_spree_permission_sets_in_core.rb +9 -0
- data/db/migrate/20240821173341_create_spree_roles_permissions_in_core.rb +9 -0
- data/db/migrate/20240821173641_add_description_to_spree_roles.rb +5 -0
- data/db/migrate/20240904152041_add_privilege_and_category_to_spree_permission_sets.rb +6 -0
- data/db/migrate/20250129061658_add_metadata_to_spree_resources.rb +28 -0
- data/db/migrate/20250201172950_add_gtin_and_condition_to_spree_variant.rb +6 -0
- data/db/migrate/20250207104016_add_primary_taxon_to_products.rb +7 -0
- data/db/migrate/20250221152004_add_metadata_to_users.rb +13 -0
- data/db/seeds.rb +1 -0
- data/lib/generators/solidus/install/app_templates/authentication/custom.rb +0 -5
- data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
- data/lib/generators/solidus/install/install_generator.rb +64 -15
- data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +15 -12
- data/lib/generators/solidus/update/update_generator.rb +1 -1
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/application.rb.tt +1 -1
- data/lib/generators/spree/dummy/templates/rails/database.yml +41 -93
- data/lib/generators/spree/dummy/templates/rails/manifest.js +3 -0
- data/lib/generators/spree/dummy/templates/rails/test.rb +6 -1
- data/lib/spree/app_configuration.rb +102 -67
- data/lib/spree/core/class_constantizer.rb +2 -2
- data/lib/spree/core/controller_helpers/auth.rb +5 -61
- data/lib/spree/core/controller_helpers/common.rb +5 -80
- data/lib/spree/core/controller_helpers/order.rb +5 -86
- data/lib/spree/core/controller_helpers/payment_parameters.rb +5 -163
- data/lib/spree/core/controller_helpers/pricing.rb +5 -17
- data/lib/spree/core/controller_helpers/search.rb +5 -14
- data/lib/spree/core/controller_helpers/store.rb +5 -17
- data/lib/spree/core/controller_helpers/strong_parameters.rb +5 -71
- data/lib/spree/core/engine.rb +13 -5
- data/lib/spree/core/environment/calculators.rb +35 -3
- data/lib/spree/core/environment/promotions.rb +25 -4
- data/lib/spree/core/environment_extension.rb +16 -2
- data/lib/spree/core/importer/order.rb +5 -5
- data/lib/spree/core/importer/product.rb +3 -3
- data/lib/spree/core/nested_class_set.rb +28 -0
- data/lib/spree/core/null_promotion_configuration.rb +84 -0
- data/lib/spree/core/product_filters.rb +1 -1
- data/lib/spree/core/search/variant.rb +2 -2
- data/lib/spree/core/state_machines/inventory_unit.rb +5 -40
- data/lib/spree/core/state_machines/order.rb +5 -251
- data/lib/spree/core/state_machines/payment.rb +5 -59
- data/lib/spree/core/state_machines/reimbursement.rb +5 -31
- data/lib/spree/core/state_machines/return_authorization.rb +5 -30
- data/lib/spree/core/state_machines/return_item/acceptance_status.rb +5 -49
- data/lib/spree/core/state_machines/return_item/reception_status.rb +5 -40
- data/lib/spree/core/state_machines/shipment.rb +5 -56
- data/lib/spree/core/state_machines.rb +48 -81
- data/lib/spree/core/validators/email.rb +1 -1
- data/lib/spree/core/version.rb +2 -2
- data/lib/spree/core.rb +2 -14
- data/lib/spree/deprecator.rb +9 -0
- data/lib/spree/i18n.rb +1 -1
- data/lib/spree/mailer_previews/carton_preview.rb +1 -1
- data/lib/spree/money.rb +5 -118
- data/lib/spree/permission_sets/base.rb +5 -30
- data/lib/spree/permission_sets/configuration_display.rb +5 -41
- data/lib/spree/permission_sets/configuration_management.rb +5 -40
- data/lib/spree/permission_sets/dashboard_display.rb +5 -14
- data/lib/spree/permission_sets/default_customer.rb +5 -71
- data/lib/spree/permission_sets/order_display.rb +5 -38
- data/lib/spree/permission_sets/order_management.rb +5 -38
- data/lib/spree/permission_sets/product_display.rb +5 -31
- data/lib/spree/permission_sets/product_management.rb +5 -35
- data/lib/spree/permission_sets/restricted_stock_display.rb +5 -21
- data/lib/spree/permission_sets/restricted_stock_management.rb +5 -21
- data/lib/spree/permission_sets/stock_display.rb +5 -14
- data/lib/spree/permission_sets/stock_management.rb +5 -14
- data/lib/spree/permission_sets/super_user.rb +5 -14
- data/lib/spree/permission_sets/user_display.rb +5 -15
- data/lib/spree/permission_sets/user_management.rb +5 -32
- data/lib/spree/permission_sets.rb +5 -18
- data/lib/spree/permitted_attributes.rb +21 -9
- data/lib/spree/preferences/configuration.rb +4 -0
- data/lib/spree/preferences/persistable.rb +7 -1
- data/lib/spree/preferences/store.rb +2 -2
- data/lib/spree/testing_support/capybara_ext.rb +11 -1
- data/lib/spree/testing_support/common_rake.rb +1 -0
- data/lib/spree/testing_support/dummy_ability.rb +7 -0
- data/lib/spree/testing_support/dummy_app/assets/stylesheets/solidus_admin/tailwind.css +1 -0
- data/lib/spree/testing_support/dummy_app/database.yml +37 -46
- data/lib/spree/testing_support/dummy_app/migrations.rb +8 -15
- data/lib/spree/testing_support/dummy_app/rake_tasks.rb +3 -6
- data/lib/spree/testing_support/dummy_app.rb +33 -19
- data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -2
- data/lib/spree/testing_support/factories/calculator_factory.rb +1 -5
- data/lib/spree/testing_support/factories/carton_factory.rb +2 -2
- data/lib/spree/testing_support/factories/customer_return_factory.rb +2 -2
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +3 -3
- data/lib/spree/testing_support/factories/order_factory.rb +13 -24
- data/lib/spree/testing_support/factories/product_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_item_factory.rb +5 -1
- data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
- data/lib/spree/testing_support/order_walkthrough.rb +3 -3
- data/lib/spree/testing_support/shared_examples/calculator.rb +10 -0
- data/lib/spree/testing_support/shared_examples/order_factory.rb +141 -0
- data/lib/spree/testing_support/shared_examples/working_factory.rb +15 -0
- data/lib/tasks/colorado_delivery_fee.rake +2 -2
- data/solidus_core.gemspec +7 -10
- metadata +107 -109
- data/app/jobs/spree/promotion_code_batch_job.rb +0 -26
- data/app/mailers/spree/promotion_code_batch_mailer.rb +0 -15
- data/app/models/spree/calculator/distributed_amount.rb +0 -33
- data/app/models/spree/calculator/flat_percent_item_total.rb +0 -23
- data/app/models/spree/calculator/flexi_rate.rb +0 -22
- data/app/models/spree/calculator/percent_on_line_item.rb +0 -13
- data/app/models/spree/calculator/tiered_flat_rate.rb +0 -52
- data/app/models/spree/calculator/tiered_percent.rb +0 -62
- data/app/models/spree/line_item_action.rb +0 -8
- data/app/models/spree/order_promotion.rb +0 -27
- data/app/models/spree/promotion/actions/create_adjustment.rb +0 -81
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +0 -98
- data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +0 -139
- data/app/models/spree/promotion/actions/free_shipping.rb +0 -59
- data/app/models/spree/promotion/order_adjustments_recalculator.rb +0 -92
- data/app/models/spree/promotion/rules/first_order.rb +0 -38
- data/app/models/spree/promotion/rules/first_repeat_purchase_since.rb +0 -36
- data/app/models/spree/promotion/rules/item_total.rb +0 -86
- data/app/models/spree/promotion/rules/nth_order.rb +0 -45
- data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -25
- data/app/models/spree/promotion/rules/option_value.rb +0 -50
- data/app/models/spree/promotion/rules/product.rb +0 -86
- data/app/models/spree/promotion/rules/store.rb +0 -26
- data/app/models/spree/promotion/rules/taxon.rb +0 -91
- data/app/models/spree/promotion/rules/user.rb +0 -34
- data/app/models/spree/promotion/rules/user_logged_in.rb +0 -20
- data/app/models/spree/promotion/rules/user_role.rb +0 -45
- data/app/models/spree/promotion.rb +0 -271
- data/app/models/spree/promotion_action.rb +0 -47
- data/app/models/spree/promotion_category.rb +0 -8
- data/app/models/spree/promotion_chooser.rb +0 -34
- data/app/models/spree/promotion_code/batch_builder.rb +0 -64
- data/app/models/spree/promotion_code.rb +0 -54
- data/app/models/spree/promotion_code_batch.rb +0 -27
- data/app/models/spree/promotion_handler/cart.rb +0 -75
- data/app/models/spree/promotion_handler/coupon.rb +0 -123
- data/app/models/spree/promotion_handler/page.rb +0 -26
- data/app/models/spree/promotion_handler/shipping.rb +0 -61
- data/app/models/spree/promotion_rule.rb +0 -55
- data/app/models/spree/promotion_rule_role.rb +0 -8
- data/app/models/spree/promotion_rule_store.rb +0 -10
- data/app/models/spree/promotion_rule_taxon.rb +0 -8
- data/app/models/spree/promotion_rule_user.rb +0 -10
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +0 -2
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +0 -2
- data/bin/rails +0 -13
- data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +0 -38
- data/db/migrate/20180202190713_create_promotion_rule_stores.rb +0 -12
- data/db/migrate/20180328172631_add_join_characters_to_promotion_code_batch.rb +0 -11
- data/db/migrate/20190106184413_remove_code_from_spree_promotions.rb +0 -42
- data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +0 -20
- data/db/migrate/20230322085416_remove_match_policy_from_spree_promotion.rb +0 -5
- data/db/migrate/20230325132905_remove_unused_columns_from_promotion_rules.rb +0 -6
- data/db/migrate/20230325161633_drop_unused_promo_action_line_items.rb +0 -13
- data/lib/generators/spree/dummy/templates/rails/script/rails +0 -6
- data/lib/solidus/migrations/promotions_with_code_handlers.rb +0 -66
- data/lib/spree/permission_sets/promotion_display.rb +0 -25
- data/lib/spree/permission_sets/promotion_management.rb +0 -25
- data/lib/spree/testing_support/factories/order_promotion_factory.rb +0 -8
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +0 -7
- data/lib/spree/testing_support/factories/promotion_code_factory.rb +0 -8
- data/lib/spree/testing_support/factories/promotion_factory.rb +0 -98
@@ -24,7 +24,7 @@ module Spree
|
|
24
24
|
money_method = { money_method => {} } unless money_method.is_a? Hash
|
25
25
|
money_method.each do |method_name, opts|
|
26
26
|
define_method("display_#{method_name}") do
|
27
|
-
default_opts = respond_to?(:currency) ? { currency:
|
27
|
+
default_opts = respond_to?(:currency) ? { currency: } : {}
|
28
28
|
Spree::Money.new(send(method_name), default_opts.merge(opts))
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
module Metadata
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
attribute :customer_metadata, :json, default: {}
|
9
|
+
attribute :admin_metadata, :json, default: {}
|
10
|
+
|
11
|
+
validate :validate_metadata_limits, if: :validate_metadata_enabled?
|
12
|
+
end
|
13
|
+
|
14
|
+
class_methods do
|
15
|
+
def meta_data_columns
|
16
|
+
%i[customer_metadata admin_metadata]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def validate_metadata_enabled?
|
23
|
+
Spree::Config.meta_data_validation_enabled
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate_metadata_limits
|
27
|
+
self.class.meta_data_columns.each { |column| validate_metadata_column(column) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_metadata_column(column)
|
31
|
+
config = Spree::Config
|
32
|
+
metadata = send(column)
|
33
|
+
|
34
|
+
return if metadata.nil?
|
35
|
+
|
36
|
+
# Check for maximum number of keys
|
37
|
+
validate_metadata_keys_count(metadata, column, config.meta_data_max_keys)
|
38
|
+
|
39
|
+
# Check for maximum key and value size
|
40
|
+
metadata.each do |key, value|
|
41
|
+
validate_metadata_key(key, column, config.meta_data_max_key_length)
|
42
|
+
validate_metadata_value(key, value, column, config.meta_data_max_value_length)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_metadata_keys_count(metadata, column, max_keys)
|
47
|
+
return unless metadata.keys.count > max_keys
|
48
|
+
|
49
|
+
errors.add(column, "must not have more than #{max_keys} keys")
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_metadata_key(key, column, max_key_length)
|
53
|
+
return unless key.to_s.length > max_key_length
|
54
|
+
|
55
|
+
errors.add(column, "key '#{key}' exceeds #{max_key_length} characters")
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_metadata_value(key, value, column, max_value_length)
|
59
|
+
return unless value.to_s.length > max_value_length
|
60
|
+
|
61
|
+
errors.add(column, "value for key '#{key}' exceeds #{max_value_length} characters")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -5,6 +5,8 @@ module Spree
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
+
Spree.deprecator.warn "Spree::NamedType is deprecated. Please set scopes and validations locally instead.", caller
|
9
|
+
|
8
10
|
scope :active, -> { where(active: true) }
|
9
11
|
default_scope -> { order(arel_table[:name].lower) }
|
10
12
|
|
@@ -18,8 +18,8 @@ module Spree
|
|
18
18
|
|
19
19
|
def property_name=(name)
|
20
20
|
unless name.blank?
|
21
|
-
unless property = Spree::Property.find_by(name:
|
22
|
-
property = Spree::Property.create(name
|
21
|
+
unless property = Spree::Property.find_by(name:)
|
22
|
+
property = Spree::Property.create(name:, presentation: name)
|
23
23
|
end
|
24
24
|
self.property = property
|
25
25
|
end
|
@@ -5,7 +5,7 @@ module Spree
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
has_many :user_addresses,
|
8
|
+
has_many :user_addresses, foreign_key: "user_id", class_name: "Spree::UserAddress" do
|
9
9
|
def find_first_by_address_values(address_attrs)
|
10
10
|
detect { |ua| ua.address == Spree::Address.new(address_attrs) }
|
11
11
|
end
|
@@ -22,7 +22,7 @@ module Spree
|
|
22
22
|
end
|
23
23
|
|
24
24
|
if user_address.persisted?
|
25
|
-
user_address.update!(column_for_default => true
|
25
|
+
user_address.update!(column_for_default => true)
|
26
26
|
else
|
27
27
|
user_address.write_attribute(column_for_default, true)
|
28
28
|
end
|
@@ -120,7 +120,7 @@ module Spree
|
|
120
120
|
remove_from_address_book(address_attributes[:id])
|
121
121
|
end
|
122
122
|
|
123
|
-
user_addresses.mark_default(user_address, address_type:
|
123
|
+
user_addresses.mark_default(user_address, address_type:) if default || first_one
|
124
124
|
|
125
125
|
if persisted?
|
126
126
|
user_address.save!
|
@@ -140,18 +140,18 @@ module Spree
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def mark_default_ship_address(address)
|
143
|
-
user_addresses.mark_default(user_addresses.find_by(address:
|
143
|
+
user_addresses.mark_default(user_addresses.find_by(address:))
|
144
144
|
end
|
145
145
|
|
146
146
|
def mark_default_bill_address(address)
|
147
|
-
user_addresses.mark_default(user_addresses.find_by(address:
|
147
|
+
user_addresses.mark_default(user_addresses.find_by(address:), address_type: :billing)
|
148
148
|
end
|
149
149
|
|
150
150
|
def remove_from_address_book(address_id)
|
151
|
-
user_address = user_addresses.find_by(address_id:
|
151
|
+
user_address = user_addresses.find_by(address_id:)
|
152
152
|
if user_address
|
153
153
|
remove_user_address_reference(address_id)
|
154
|
-
user_address.
|
154
|
+
user_address.destroy!
|
155
155
|
else
|
156
156
|
false
|
157
157
|
end
|
@@ -160,10 +160,9 @@ module Spree
|
|
160
160
|
private
|
161
161
|
|
162
162
|
def prepare_user_address(new_address)
|
163
|
-
user_address = user_addresses.
|
163
|
+
user_address = user_addresses.find_first_by_address_values(new_address.attributes)
|
164
164
|
user_address ||= user_addresses.build
|
165
165
|
user_address.address = new_address
|
166
|
-
user_address.archived = false
|
167
166
|
user_address
|
168
167
|
end
|
169
168
|
|
@@ -58,7 +58,7 @@ module Spree
|
|
58
58
|
def last_incomplete_spree_order(store: nil, only_frontend_viewable: true)
|
59
59
|
self_orders = orders
|
60
60
|
self_orders = self_orders.where(frontend_viewable: true) if only_frontend_viewable
|
61
|
-
self_orders = self_orders.where(store:
|
61
|
+
self_orders = self_orders.where(store:) if store
|
62
62
|
self_orders = self_orders.where('updated_at > ?', Spree::Config.completable_order_updated_cutoff_days.days.ago) if Spree::Config.completable_order_updated_cutoff_days
|
63
63
|
self_orders = self_orders.where('created_at > ?', Spree::Config.completable_order_created_cutoff_days.days.ago) if Spree::Config.completable_order_created_cutoff_days
|
64
64
|
last_order = self_orders.order(:created_at).last
|
@@ -73,8 +73,8 @@ module Spree
|
|
73
73
|
|
74
74
|
def display_available_store_credit_total(currency:)
|
75
75
|
Spree::Money.new(
|
76
|
-
available_store_credit_total(currency:
|
77
|
-
currency
|
76
|
+
available_store_credit_total(currency:),
|
77
|
+
currency:,
|
78
78
|
)
|
79
79
|
end
|
80
80
|
|
data/app/models/spree/address.rb
CHANGED
@@ -28,8 +28,10 @@ module Spree
|
|
28
28
|
|
29
29
|
self.allowed_ransackable_attributes = %w[name]
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
unless ActiveRecord::Relation.method_defined? :with_values # Rails 7.1+
|
32
|
+
scope :with_values, ->(attributes) do
|
33
|
+
where(value_attributes(attributes))
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
37
|
# @return [Address] an address with default attributes
|
@@ -95,14 +97,14 @@ module Spree
|
|
95
97
|
# @return [Hash] an ActiveMerchant compatible address hash
|
96
98
|
def active_merchant_hash
|
97
99
|
{
|
98
|
-
name
|
99
|
-
address1
|
100
|
-
address2
|
101
|
-
city
|
100
|
+
name:,
|
101
|
+
address1:,
|
102
|
+
address2:,
|
103
|
+
city:,
|
102
104
|
state: state_text,
|
103
105
|
zip: zipcode,
|
104
106
|
country: country.try(:iso),
|
105
|
-
phone:
|
107
|
+
phone:
|
106
108
|
}
|
107
109
|
end
|
108
110
|
|
@@ -130,7 +132,7 @@ module Spree
|
|
130
132
|
# @return [Country] setter that sets self.country to the Country with a matching 2 letter iso
|
131
133
|
# @raise [ActiveRecord::RecordNotFound] if country with the iso doesn't exist
|
132
134
|
def country_iso=(iso)
|
133
|
-
self.country = Spree::Country.find_by!(iso:
|
135
|
+
self.country = Spree::Country.find_by!(iso:)
|
134
136
|
end
|
135
137
|
|
136
138
|
def country_iso
|
@@ -4,29 +4,18 @@ module Spree
|
|
4
4
|
# Adjustments represent a change to the +item_total+ of an Order. Each
|
5
5
|
# adjustment has an +amount+ that can be either positive or negative.
|
6
6
|
#
|
7
|
-
# Adjustments can be "
|
7
|
+
# Adjustments can be "unfinalized" or "finalized". Once an adjustment is finalized, it
|
8
8
|
# will not be automatically updated.
|
9
|
-
#
|
10
|
-
# == Boolean attributes
|
11
|
-
#
|
12
|
-
# 1. *eligible?*
|
13
|
-
#
|
14
|
-
# This boolean attributes stores whether this adjustment is currently
|
15
|
-
# eligible for its order. Only eligible adjustments count towards the
|
16
|
-
# order's adjustment total. This allows an adjustment to be preserved if
|
17
|
-
# it becomes ineligible so it might be reinstated.
|
18
9
|
class Adjustment < Spree::Base
|
19
10
|
belongs_to :adjustable, polymorphic: true, touch: true, optional: true
|
20
11
|
belongs_to :source, polymorphic: true, optional: true
|
21
12
|
belongs_to :order, class_name: 'Spree::Order', inverse_of: :all_adjustments, optional: true
|
22
|
-
belongs_to :promotion_code, class_name: 'Spree::PromotionCode', optional: true
|
23
13
|
belongs_to :adjustment_reason, class_name: 'Spree::AdjustmentReason', inverse_of: :adjustments, optional: true
|
24
14
|
|
25
15
|
validates :adjustable, presence: true
|
26
16
|
validates :order, presence: true
|
27
17
|
validates :label, presence: true
|
28
18
|
validates :amount, numericality: true
|
29
|
-
validates :promotion_code, presence: true, if: :require_promotion_code?
|
30
19
|
|
31
20
|
scope :not_finalized, -> { where(finalized: false) }
|
32
21
|
scope :finalized, -> { where(finalized: true) }
|
@@ -38,16 +27,23 @@ module Spree
|
|
38
27
|
end
|
39
28
|
scope :price, -> { where(adjustable_type: 'Spree::LineItem') }
|
40
29
|
scope :shipping, -> { where(adjustable_type: 'Spree::Shipment') }
|
41
|
-
scope :eligible, -> {
|
30
|
+
scope :eligible, -> { all }
|
31
|
+
class << self
|
32
|
+
deprecate :eligible, deprecator: Spree.deprecator
|
33
|
+
end
|
42
34
|
scope :charge, -> { where("#{quoted_table_name}.amount >= 0") }
|
43
35
|
scope :credit, -> { where("#{quoted_table_name}.amount < 0") }
|
44
36
|
scope :nonzero, -> { where("#{quoted_table_name}.amount != 0") }
|
45
|
-
scope :promotion, -> { where(source_type:
|
46
|
-
scope :non_promotion, -> { where.not(source_type:
|
37
|
+
scope :promotion, -> { where(source_type: Spree::Config.adjustment_promotion_source_types.map(&:to_s)) }
|
38
|
+
scope :non_promotion, -> { where.not(source_type: Spree::Config.adjustment_promotion_source_types.map(&:to_s)) }
|
47
39
|
scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
|
48
40
|
scope :is_included, -> { where(included: true) }
|
49
41
|
scope :additional, -> { where(included: false) }
|
50
42
|
|
43
|
+
singleton_class.deprecate :return_authorization, deprecator: Spree.deprecator
|
44
|
+
|
45
|
+
allowed_ransackable_attributes << 'label'
|
46
|
+
|
51
47
|
extend DisplayMoney
|
52
48
|
money_methods :amount
|
53
49
|
|
@@ -73,7 +69,7 @@ module Spree
|
|
73
69
|
|
74
70
|
# @return [Boolean] true when this is a promotion adjustment (Promotion adjustments have a {PromotionAction} source)
|
75
71
|
def promotion?
|
76
|
-
source_type
|
72
|
+
source_type.to_s.in?(Spree::Config.adjustment_promotion_source_types.map(&:to_s))
|
77
73
|
end
|
78
74
|
|
79
75
|
# @return [Boolean] true when this is a tax adjustment (Tax adjustments have a {TaxRate} source)
|
@@ -86,55 +82,9 @@ module Spree
|
|
86
82
|
source_type == 'Spree::UnitCancel'
|
87
83
|
end
|
88
84
|
|
89
|
-
|
90
|
-
|
91
|
-
#
|
92
|
-
# If the adjustment has no source (such as when created manually from the
|
93
|
-
# admin) or is closed, this is a noop.
|
94
|
-
#
|
95
|
-
# @return [BigDecimal] New amount of this adjustment
|
96
|
-
def recalculate
|
97
|
-
if finalized? && !tax?
|
98
|
-
return amount
|
99
|
-
end
|
100
|
-
|
101
|
-
# If the adjustment has no source, do not attempt to re-calculate the
|
102
|
-
# amount.
|
103
|
-
# Some scenarios where this happens:
|
104
|
-
# - Adjustments that are manually created via the admin backend
|
105
|
-
# - PromotionAction adjustments where the PromotionAction was deleted
|
106
|
-
# after the order was completed.
|
107
|
-
if source.present?
|
108
|
-
self.amount = source.compute_amount(adjustable)
|
109
|
-
|
110
|
-
if promotion?
|
111
|
-
self.eligible = calculate_eligibility
|
112
|
-
end
|
113
|
-
|
114
|
-
# Persist only if changed
|
115
|
-
# This is only not a save! to avoid the extra queries to load the order
|
116
|
-
# (for validations) and to touch the adjustment.
|
117
|
-
update_columns(eligible: eligible, amount: amount, updated_at: Time.current) if changed?
|
118
|
-
end
|
119
|
-
amount
|
120
|
-
end
|
121
|
-
|
122
|
-
# Calculates based on attached promotion (if this is a promotion
|
123
|
-
# adjustment) whether this promotion is still eligible.
|
124
|
-
# @api private
|
125
|
-
# @return [true,false] Whether this adjustment is eligible
|
126
|
-
def calculate_eligibility
|
127
|
-
if !finalized? && source && promotion?
|
128
|
-
source.promotion.eligible?(adjustable, promotion_code: promotion_code)
|
129
|
-
else
|
130
|
-
eligible?
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def require_promotion_code?
|
137
|
-
promotion? && !source.promotion.apply_automatically && source.promotion.codes.any?
|
85
|
+
def eligible?
|
86
|
+
true
|
138
87
|
end
|
88
|
+
alias_method :eligible, :eligible?
|
139
89
|
end
|
140
90
|
end
|
@@ -14,7 +14,7 @@ module Spree
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def weighted_order_adjustment_amount(inventory_unit)
|
17
|
-
inventory_unit.order.adjustments.
|
17
|
+
inventory_unit.order.adjustments.non_tax.sum(:amount) * percentage_of_order_total(inventory_unit)
|
18
18
|
end
|
19
19
|
|
20
20
|
def weighted_line_item_amount(inventory_unit)
|
data/app/models/spree/carton.rb
CHANGED
@@ -46,11 +46,11 @@ class Spree::Carton < Spree::Base
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def manifest
|
49
|
-
@manifest ||= Spree::ShippingManifest.new(inventory_units:
|
49
|
+
@manifest ||= Spree::ShippingManifest.new(inventory_units:).items
|
50
50
|
end
|
51
51
|
|
52
52
|
def manifest_for_order(order)
|
53
|
-
Spree::ShippingManifest.new(inventory_units:
|
53
|
+
Spree::ShippingManifest.new(inventory_units:).for_order(order).items
|
54
54
|
end
|
55
55
|
|
56
56
|
def any_exchanges?
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
module Core
|
5
|
+
class StateMachines
|
6
|
+
# Inventory Units' state machine
|
7
|
+
#
|
8
|
+
# for each event the following instance methods are dynamically implemented:
|
9
|
+
# #<event_name>
|
10
|
+
# #<event_name>!
|
11
|
+
# #can_<event_name>?
|
12
|
+
#
|
13
|
+
# for each state the following instance methods are implemented:
|
14
|
+
# #<state_name>?
|
15
|
+
#
|
16
|
+
module InventoryUnit
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
included do
|
20
|
+
state_machine initial: :on_hand do
|
21
|
+
event :fill_backorder do
|
22
|
+
transition to: :on_hand, from: :backordered
|
23
|
+
end
|
24
|
+
after_transition on: :fill_backorder, do: :fulfill_order
|
25
|
+
|
26
|
+
event :ship do
|
27
|
+
transition to: :shipped, if: :allow_ship?
|
28
|
+
end
|
29
|
+
|
30
|
+
event :return do
|
31
|
+
transition to: :returned, from: :shipped
|
32
|
+
end
|
33
|
+
|
34
|
+
event :cancel do
|
35
|
+
transition to: :canceled, from: ::Spree::InventoryUnit::CANCELABLE_STATES.map(&:to_sym)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
module Core
|
5
|
+
class StateMachines
|
6
|
+
module Order
|
7
|
+
module ClassMethods
|
8
|
+
attr_accessor :previous_states
|
9
|
+
attr_writer :next_event_transitions, :checkout_steps, :removed_transitions
|
10
|
+
|
11
|
+
def checkout_flow(&block)
|
12
|
+
if block_given?
|
13
|
+
@checkout_flow = block
|
14
|
+
define_state_machine!
|
15
|
+
else
|
16
|
+
@checkout_flow
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def define_state_machine!
|
21
|
+
self.checkout_steps = {}
|
22
|
+
self.next_event_transitions = []
|
23
|
+
self.previous_states = [:cart]
|
24
|
+
self.removed_transitions = []
|
25
|
+
|
26
|
+
# Build the checkout flow using the checkout_flow defined either
|
27
|
+
# within the Order class, or a decorator for that class.
|
28
|
+
#
|
29
|
+
# This method may be called multiple times depending on if the
|
30
|
+
# checkout_flow is re-defined in a decorator or not.
|
31
|
+
instance_eval(&checkout_flow)
|
32
|
+
|
33
|
+
klass = self
|
34
|
+
|
35
|
+
# To avoid multiple occurrences of the same transition being defined
|
36
|
+
# On first definition, state_machines will not be defined
|
37
|
+
state_machines.clear if respond_to?(:state_machines)
|
38
|
+
state_machine :state, initial: :cart, use_transactions: false do
|
39
|
+
klass.next_event_transitions.each { |state| transition(state.merge(on: :next)) }
|
40
|
+
|
41
|
+
# Persist the state on the order
|
42
|
+
after_transition do |order, transition|
|
43
|
+
# Hard to say if this is really necessary, it was introduced in this commit:
|
44
|
+
# https://github.com/mamhoff/solidus/commit/fa1d66c42e4c04ee7cd1c20d87e4cdb74a226d3d
|
45
|
+
# But it seems to be harmless, so we'll keep it for now.
|
46
|
+
order.state = order.state # rubocop:disable Lint/SelfAssignment
|
47
|
+
|
48
|
+
order.state_changes.create(
|
49
|
+
previous_state: transition.from,
|
50
|
+
next_state: transition.to,
|
51
|
+
name: 'order',
|
52
|
+
user_id: order.user_id
|
53
|
+
)
|
54
|
+
order.save
|
55
|
+
end
|
56
|
+
|
57
|
+
event :cancel do
|
58
|
+
transition to: :canceled, if: :allow_cancel?, from: :complete
|
59
|
+
end
|
60
|
+
|
61
|
+
event :return do
|
62
|
+
transition to: :returned, from: [:complete, :awaiting_return], if: :all_inventory_units_returned?
|
63
|
+
end
|
64
|
+
|
65
|
+
event :resume do
|
66
|
+
transition to: :resumed, from: :canceled, if: :canceled?
|
67
|
+
end
|
68
|
+
|
69
|
+
event :authorize_return do
|
70
|
+
transition to: :awaiting_return, from: :complete
|
71
|
+
end
|
72
|
+
|
73
|
+
event :complete do
|
74
|
+
transition to: :complete, from: klass.checkout_steps.keys.last
|
75
|
+
end
|
76
|
+
|
77
|
+
if states[:payment]
|
78
|
+
event :payment_failed do
|
79
|
+
transition to: :payment, from: :confirm
|
80
|
+
end
|
81
|
+
|
82
|
+
after_transition to: :complete, do: :add_payment_sources_to_wallet
|
83
|
+
before_transition to: :payment, do: :add_default_payment_from_wallet
|
84
|
+
before_transition to: :payment, do: :ensure_billing_address
|
85
|
+
|
86
|
+
before_transition to: :confirm, do: :add_store_credit_payments
|
87
|
+
|
88
|
+
# see also process_payments_before_complete below which needs to
|
89
|
+
# be added in the correct sequence.
|
90
|
+
end
|
91
|
+
|
92
|
+
before_transition from: :cart, do: :ensure_line_items_present
|
93
|
+
|
94
|
+
if states[:address]
|
95
|
+
before_transition to: :address, do: :assign_default_user_addresses
|
96
|
+
before_transition from: :address, do: :persist_user_address!
|
97
|
+
end
|
98
|
+
|
99
|
+
if states[:delivery]
|
100
|
+
before_transition to: :delivery, do: :ensure_shipping_address
|
101
|
+
before_transition to: :delivery, do: :create_proposed_shipments
|
102
|
+
before_transition to: :delivery, do: :ensure_available_shipping_rates
|
103
|
+
end
|
104
|
+
|
105
|
+
before_transition to: :resumed, do: :ensure_line_item_variants_are_not_deleted
|
106
|
+
before_transition to: :resumed, do: :validate_line_item_availability
|
107
|
+
|
108
|
+
# Sequence of before_transition to: :complete
|
109
|
+
# calls matter so that we do not process payments
|
110
|
+
# until validations have passed
|
111
|
+
before_transition to: :complete, do: :validate_line_item_availability
|
112
|
+
before_transition to: :complete, do: :ensure_promotions_eligible
|
113
|
+
before_transition to: :complete, do: :ensure_line_item_variants_are_not_deleted
|
114
|
+
before_transition to: :complete, do: :ensure_inventory_units
|
115
|
+
if states[:payment]
|
116
|
+
before_transition to: :complete, do: :process_payments_before_complete
|
117
|
+
end
|
118
|
+
|
119
|
+
after_transition to: :complete, do: :finalize
|
120
|
+
after_transition to: :resumed, do: :after_resume
|
121
|
+
after_transition to: :canceled, do: :after_cancel
|
122
|
+
|
123
|
+
after_transition from: any - :cart, to: any - [:confirm, :complete] do |order|
|
124
|
+
order.recalculate
|
125
|
+
end
|
126
|
+
|
127
|
+
after_transition do |order, transition|
|
128
|
+
order.logger.debug "Order #{order.number} transitioned from #{transition.from} to #{transition.to} via #{transition.event}"
|
129
|
+
end
|
130
|
+
|
131
|
+
after_failure do |order, transition|
|
132
|
+
order.logger.debug "Order #{order.number} halted transition on event #{transition.event} state #{transition.from}: #{order.errors.full_messages.join}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def go_to_state(name, options = {})
|
138
|
+
checkout_steps[name] = options
|
139
|
+
previous_states.each do |state|
|
140
|
+
add_transition({ from: state, to: name }.merge(options))
|
141
|
+
end
|
142
|
+
if options[:if]
|
143
|
+
previous_states << name
|
144
|
+
else
|
145
|
+
self.previous_states = [name]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def insert_checkout_step(name, options = {})
|
150
|
+
before = options.delete(:before)
|
151
|
+
after = options.delete(:after) unless before
|
152
|
+
after = checkout_steps.keys.last unless before || after
|
153
|
+
|
154
|
+
cloned_steps = checkout_steps.clone
|
155
|
+
cloned_removed_transitions = removed_transitions.clone
|
156
|
+
checkout_flow do
|
157
|
+
cloned_steps.each_pair do |key, value|
|
158
|
+
go_to_state(name, options) if key == before
|
159
|
+
go_to_state(key, value)
|
160
|
+
go_to_state(name, options) if key == after
|
161
|
+
end
|
162
|
+
cloned_removed_transitions.each do |transition|
|
163
|
+
remove_transition(transition)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def remove_checkout_step(name)
|
169
|
+
cloned_steps = checkout_steps.clone
|
170
|
+
cloned_removed_transitions = removed_transitions.clone
|
171
|
+
checkout_flow do
|
172
|
+
cloned_steps.each_pair do |key, value|
|
173
|
+
go_to_state(key, value) unless key == name
|
174
|
+
end
|
175
|
+
cloned_removed_transitions.each do |transition|
|
176
|
+
remove_transition(transition)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def remove_transition(options = {})
|
182
|
+
removed_transitions << options
|
183
|
+
next_event_transitions.delete(find_transition(options))
|
184
|
+
end
|
185
|
+
|
186
|
+
def find_transition(options = {})
|
187
|
+
return nil if options.nil? || !options.include?(:from) || !options.include?(:to)
|
188
|
+
|
189
|
+
next_event_transitions.detect do |transition|
|
190
|
+
transition[options[:from].to_sym] == options[:to].to_sym
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def next_event_transitions
|
195
|
+
@next_event_transitions ||= []
|
196
|
+
end
|
197
|
+
|
198
|
+
def checkout_steps
|
199
|
+
@checkout_steps ||= {}
|
200
|
+
end
|
201
|
+
|
202
|
+
def checkout_step_names
|
203
|
+
checkout_steps.keys
|
204
|
+
end
|
205
|
+
|
206
|
+
def add_transition(options)
|
207
|
+
next_event_transitions << { options.delete(:from) => options.delete(:to) }.merge(options)
|
208
|
+
end
|
209
|
+
|
210
|
+
def removed_transitions
|
211
|
+
@removed_transitions ||= []
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
module Core
|
5
|
+
class StateMachines
|
6
|
+
module Order
|
7
|
+
def self.included(klass)
|
8
|
+
klass.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
def checkout_steps
|
12
|
+
steps = self.class.checkout_steps.each_with_object([]) { |(step, options), checkout_steps|
|
13
|
+
next if options.include?(:if) && !options[:if].call(self)
|
14
|
+
|
15
|
+
checkout_steps << step
|
16
|
+
}.map(&:to_s)
|
17
|
+
# Ensure there is always a complete step
|
18
|
+
steps << "complete" unless steps.include?("complete")
|
19
|
+
steps
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_checkout_step?(step)
|
23
|
+
step.present? && checkout_steps.include?(step)
|
24
|
+
end
|
25
|
+
|
26
|
+
def passed_checkout_step?(step)
|
27
|
+
has_checkout_step?(step) && checkout_step_index(step) < checkout_step_index(state)
|
28
|
+
end
|
29
|
+
|
30
|
+
def checkout_step_index(step)
|
31
|
+
checkout_steps.index(step).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def can_go_to_state?(state)
|
35
|
+
return false unless has_checkout_step?(self.state) && has_checkout_step?(state)
|
36
|
+
|
37
|
+
checkout_step_index(state) > checkout_step_index(self.state)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|