solidus_core 4.3.4 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +2 -2
- 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/ordered_property_value_list.rb +2 -2
- data/app/models/concerns/spree/user_address_book.rb +4 -4
- data/app/models/concerns/spree/user_methods.rb +3 -3
- data/app/models/spree/address.rb +6 -6
- data/app/models/spree/adjustment.rb +13 -66
- data/app/models/spree/calculator/returns/default_refund_amount.rb +1 -1
- data/app/models/spree/carton.rb +2 -2
- data/app/models/spree/credit_card.rb +6 -6
- 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/line_item.rb +1 -1
- 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/order.rb +15 -22
- data/app/models/spree/order_cancellations.rb +8 -8
- data/app/models/spree/order_mutex.rb +2 -2
- data/app/models/spree/order_shipping.rb +9 -9
- data/app/models/spree/order_updater.rb +6 -10
- data/app/models/spree/payment/processing.rb +2 -2
- data/app/models/spree/payment.rb +2 -2
- data/app/models/spree/payment_create.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +1 -1
- data/app/models/spree/payment_source.rb +5 -1
- data/app/models/spree/permission_set.rb +11 -0
- data/app/models/spree/product.rb +7 -28
- data/app/models/spree/refund.rb +1 -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/return_item.rb +9 -9
- data/app/models/spree/role.rb +3 -1
- data/app/models/spree/role_permission.rb +8 -0
- data/app/models/spree/shipment.rb +7 -7
- data/app/models/spree/shipping_category.rb +2 -0
- data/app/models/spree/shipping_rate.rb +1 -1
- data/app/models/spree/{order_contents.rb → simple_order_contents.rb} +4 -11
- 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 +1 -1
- data/app/models/spree/stock_location.rb +5 -5
- data/app/models/spree/store.rb +1 -1
- data/app/models/spree/store_credit.rb +17 -15
- data/app/models/spree/store_credit_event.rb +3 -3
- data/app/models/spree/tax_calculator/default.rb +2 -2
- 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 +3 -3
- data/app/models/spree/taxonomy.rb +2 -2
- data/app/models/spree/unit_cancel.rb +1 -2
- data/app/models/spree/variant/vat_price_generator.rb +1 -1
- data/app/models/spree/variant.rb +7 -2
- 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/config/locales/en.yml +4 -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 -117
- 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/seeds.rb +1 -0
- data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
- data/lib/generators/solidus/update/update_generator.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/test.rb +6 -1
- data/lib/spree/app_configuration.rb +53 -84
- data/lib/spree/core/class_constantizer.rb +2 -2
- data/lib/spree/core/controller_helpers/payment_parameters.rb +1 -1
- data/lib/spree/core/engine.rb +1 -0
- 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/order.rb +0 -1
- data/lib/spree/core/validators/email.rb +1 -1
- data/lib/spree/core/version.rb +2 -2
- data/lib/spree/core.rb +2 -6
- 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/permission_sets/base.rb +13 -1
- data/lib/spree/permission_sets/configuration_display.rb +10 -0
- data/lib/spree/permission_sets/configuration_management.rb +10 -0
- data/lib/spree/permission_sets/dashboard_display.rb +12 -0
- data/lib/spree/permission_sets/default_customer.rb +11 -1
- data/lib/spree/permission_sets/order_display.rb +10 -0
- data/lib/spree/permission_sets/order_management.rb +10 -0
- data/lib/spree/permission_sets/product_display.rb +10 -0
- data/lib/spree/permission_sets/product_management.rb +10 -0
- data/lib/spree/permission_sets/restricted_stock_display.rb +10 -0
- data/lib/spree/permission_sets/restricted_stock_management.rb +10 -0
- data/lib/spree/permission_sets/stock_display.rb +10 -0
- data/lib/spree/permission_sets/stock_management.rb +10 -0
- data/lib/spree/permission_sets/super_user.rb +10 -0
- data/lib/spree/permission_sets/user_display.rb +10 -0
- data/lib/spree/permission_sets/user_management.rb +10 -0
- data/lib/spree/permission_sets.rb +0 -2
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/preferences/store.rb +2 -2
- data/lib/spree/testing_support/capybara_ext.rb +1 -1
- data/lib/spree/testing_support/dummy_ability.rb +7 -0
- data/lib/spree/testing_support/dummy_app/database.yml +2 -2
- data/lib/spree/testing_support/dummy_app/migrations.rb +8 -15
- data/lib/spree/testing_support/dummy_app/rake_tasks.rb +2 -2
- data/lib/spree/testing_support/dummy_app.rb +17 -12
- 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 +5 -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 +6 -6
- metadata +60 -91
- 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/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/minimum_quantity.rb +0 -59
- 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_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/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/db/migrate/20231027084517_add_order_promotions_foreign_key.rb +0 -10
- data/db/migrate/20231031175215_add_promotion_order_promotion_foreign_key.rb +0 -10
- 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/ransack_4_1_patch.rb +0 -16
- 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
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
module PromotionHandler
|
5
|
-
class Coupon
|
6
|
-
attr_reader :order, :coupon_code
|
7
|
-
attr_accessor :error, :success, :status_code
|
8
|
-
|
9
|
-
def initialize(order)
|
10
|
-
@order = order
|
11
|
-
@coupon_code = order.coupon_code && order.coupon_code.downcase
|
12
|
-
end
|
13
|
-
|
14
|
-
def apply
|
15
|
-
if coupon_code.present?
|
16
|
-
if promotion.present? && promotion.active? && promotion.actions.exists?
|
17
|
-
handle_present_promotion(promotion)
|
18
|
-
elsif promotion_code&.promotion&.expired?
|
19
|
-
set_error_code :coupon_code_expired
|
20
|
-
else
|
21
|
-
set_error_code :coupon_code_not_found
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
def remove
|
29
|
-
if promotion.blank?
|
30
|
-
set_error_code :coupon_code_not_found
|
31
|
-
elsif !promotion_exists_on_order?(order, promotion)
|
32
|
-
set_error_code :coupon_code_not_present
|
33
|
-
else
|
34
|
-
promotion.remove_from(order)
|
35
|
-
order.recalculate
|
36
|
-
set_success_code :coupon_code_removed
|
37
|
-
end
|
38
|
-
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
def set_success_code(status_code)
|
43
|
-
@status_code = status_code
|
44
|
-
@success = I18n.t(status_code, scope: 'spree')
|
45
|
-
end
|
46
|
-
|
47
|
-
def set_error_code(status_code, options = {})
|
48
|
-
@status_code = status_code
|
49
|
-
@error = options[:error] || I18n.t(status_code, scope: 'spree')
|
50
|
-
end
|
51
|
-
|
52
|
-
def promotion
|
53
|
-
@promotion ||= begin
|
54
|
-
if promotion_code && promotion_code.promotion.active?
|
55
|
-
promotion_code.promotion
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def successful?
|
61
|
-
success.present? && error.blank?
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def promotion_code
|
67
|
-
@promotion_code ||= Spree::PromotionCode.where(value: coupon_code).first
|
68
|
-
end
|
69
|
-
|
70
|
-
def handle_present_promotion(promotion)
|
71
|
-
return promotion_usage_limit_exceeded if promotion.usage_limit_exceeded? || promotion_code.usage_limit_exceeded?
|
72
|
-
return promotion_applied if promotion_exists_on_order?(order, promotion)
|
73
|
-
|
74
|
-
unless promotion.eligible?(order, promotion_code: promotion_code)
|
75
|
-
set_promotion_eligibility_error_code(promotion)
|
76
|
-
return error || ineligible_for_this_order
|
77
|
-
end
|
78
|
-
|
79
|
-
# If any of the actions for the promotion return `true`,
|
80
|
-
# then result here will also be `true`.
|
81
|
-
result = promotion.activate(order: order, promotion_code: promotion_code)
|
82
|
-
if result
|
83
|
-
order.recalculate
|
84
|
-
set_success_code :coupon_code_applied
|
85
|
-
else
|
86
|
-
set_error_code :coupon_code_unknown_error
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def set_promotion_eligibility_error_code(promotion)
|
91
|
-
return unless eligibility_error_code_present?(promotion)
|
92
|
-
|
93
|
-
eligibility_error = promotion.eligibility_errors.details[:base].first
|
94
|
-
|
95
|
-
@status_code = eligibility_error[:error_code]
|
96
|
-
@error = eligibility_error[:error]
|
97
|
-
end
|
98
|
-
|
99
|
-
def promotion_usage_limit_exceeded
|
100
|
-
set_error_code :coupon_code_max_usage
|
101
|
-
end
|
102
|
-
|
103
|
-
def ineligible_for_this_order
|
104
|
-
set_error_code :coupon_code_not_eligible
|
105
|
-
end
|
106
|
-
|
107
|
-
def promotion_applied
|
108
|
-
set_error_code :coupon_code_already_applied
|
109
|
-
end
|
110
|
-
|
111
|
-
def promotion_exists_on_order?(order, promotion)
|
112
|
-
order.promotions.include? promotion
|
113
|
-
end
|
114
|
-
|
115
|
-
def eligibility_error_code_present?(promotion)
|
116
|
-
promotion.eligibility_errors.present? &&
|
117
|
-
promotion.eligibility_errors.details.present? &&
|
118
|
-
promotion.eligibility_errors.details.key?(:base) &&
|
119
|
-
promotion.eligibility_errors.details[:base].first[:error_code].present?
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
module PromotionHandler
|
5
|
-
class Page
|
6
|
-
attr_reader :order, :path
|
7
|
-
|
8
|
-
def initialize(order, path)
|
9
|
-
@order = order
|
10
|
-
@path = path.gsub(/\A\//, '')
|
11
|
-
end
|
12
|
-
|
13
|
-
def activate
|
14
|
-
if promotion && promotion.eligible?(order)
|
15
|
-
promotion.activate(order: order)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def promotion
|
22
|
-
@promotion ||= Spree::Promotion.active.find_by(path: path)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
module PromotionHandler
|
5
|
-
# Used for activating promotions with shipping rules
|
6
|
-
class Shipping
|
7
|
-
attr_reader :order
|
8
|
-
attr_accessor :error, :success
|
9
|
-
|
10
|
-
def initialize(order)
|
11
|
-
@order = order
|
12
|
-
end
|
13
|
-
|
14
|
-
def activate
|
15
|
-
connected_promotions.each do |order_promotion|
|
16
|
-
if order_promotion.promotion.eligible?(order)
|
17
|
-
order_promotion.promotion.activate(
|
18
|
-
order: order,
|
19
|
-
promotion_code: order_promotion.promotion_code,
|
20
|
-
)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
not_connected_automatic_promotions.each do |promotion|
|
25
|
-
if promotion.eligible?(order)
|
26
|
-
promotion.activate(order: order)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def not_connected_automatic_promotions
|
34
|
-
automatic_promotions - connected_promotions.map(&:promotion)
|
35
|
-
end
|
36
|
-
|
37
|
-
def automatic_promotions
|
38
|
-
@automatic_promotions ||= active_shipping_promotions.
|
39
|
-
where(apply_automatically: true).
|
40
|
-
to_a.
|
41
|
-
uniq
|
42
|
-
end
|
43
|
-
|
44
|
-
def connected_promotions
|
45
|
-
@connected_promotions ||= order.order_promotions.
|
46
|
-
joins(:promotion).
|
47
|
-
includes(:promotion).
|
48
|
-
merge(active_shipping_promotions).
|
49
|
-
to_a.
|
50
|
-
uniq
|
51
|
-
end
|
52
|
-
|
53
|
-
def active_shipping_promotions
|
54
|
-
Spree::Promotion.all.
|
55
|
-
active.
|
56
|
-
joins(:promotion_actions).
|
57
|
-
merge(Spree::PromotionAction.shipping)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spree/preferences/persistable'
|
4
|
-
|
5
|
-
module Spree
|
6
|
-
# Base class for all promotion rules
|
7
|
-
class PromotionRule < Spree::Base
|
8
|
-
include Spree::Preferences::Persistable
|
9
|
-
|
10
|
-
belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_rules, optional: true
|
11
|
-
|
12
|
-
scope :of_type, ->(type) { where(type: type) }
|
13
|
-
|
14
|
-
validates :promotion, presence: true
|
15
|
-
validate :unique_per_promotion, on: :create
|
16
|
-
|
17
|
-
def preload_relations
|
18
|
-
[]
|
19
|
-
end
|
20
|
-
|
21
|
-
def applicable?(_promotable)
|
22
|
-
raise NotImplementedError, "applicable? should be implemented in a sub-class of Spree::PromotionRule"
|
23
|
-
end
|
24
|
-
|
25
|
-
def eligible?(_promotable, _options = {})
|
26
|
-
raise NotImplementedError, "eligible? should be implemented in a sub-class of Spree::PromotionRule"
|
27
|
-
end
|
28
|
-
|
29
|
-
# This states if a promotion can be applied to the specified line item
|
30
|
-
# It is true by default, but can be overridden by promotion rules to provide conditions
|
31
|
-
def actionable?(_line_item)
|
32
|
-
true
|
33
|
-
end
|
34
|
-
|
35
|
-
def eligibility_errors
|
36
|
-
@eligibility_errors ||= ActiveModel::Errors.new(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_partial_path
|
40
|
-
"spree/admin/promotions/rules/#{model_name.element}"
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def unique_per_promotion
|
46
|
-
if Spree::PromotionRule.exists?(promotion_id: promotion_id, type: self.class.name)
|
47
|
-
errors[:base] << "Promotion already contains this rule type"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def eligibility_error_message(key, options = {})
|
52
|
-
I18n.t(key, **{ scope: [:spree, :eligibility_errors, :messages] }.merge(options))
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
class PromotionRuleStore < Spree::Base
|
5
|
-
self.table_name = "spree_promotion_rules_stores"
|
6
|
-
|
7
|
-
belongs_to :promotion_rule, class_name: "Spree::PromotionRule", optional: true
|
8
|
-
belongs_to :store, class_name: "Spree::Store", optional: true
|
9
|
-
end
|
10
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
class PromotionRuleUser < Spree::Base
|
5
|
-
self.table_name = 'spree_promotion_rules_users'
|
6
|
-
|
7
|
-
belongs_to :promotion_rule, class_name: 'Spree::PromotionRule', optional: true
|
8
|
-
belongs_to :user, class_name: Spree::UserClassHandle.new, optional: true
|
9
|
-
end
|
10
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class CreateSpreePromotionCodeBatch < ActiveRecord::Migration[5.0]
|
4
|
-
def change
|
5
|
-
create_table :spree_promotion_code_batches do |t|
|
6
|
-
t.references :promotion, null: false, index: true
|
7
|
-
t.string :base_code, null: false
|
8
|
-
t.integer :number_of_codes, null: false
|
9
|
-
t.string :email
|
10
|
-
t.string :error
|
11
|
-
t.string :state, default: "pending"
|
12
|
-
t.timestamps precision: 6
|
13
|
-
end
|
14
|
-
|
15
|
-
add_foreign_key(
|
16
|
-
:spree_promotion_code_batches,
|
17
|
-
:spree_promotions,
|
18
|
-
column: :promotion_id
|
19
|
-
)
|
20
|
-
|
21
|
-
add_column(
|
22
|
-
:spree_promotion_codes,
|
23
|
-
:promotion_code_batch_id,
|
24
|
-
:integer
|
25
|
-
)
|
26
|
-
|
27
|
-
add_foreign_key(
|
28
|
-
:spree_promotion_codes,
|
29
|
-
:spree_promotion_code_batches,
|
30
|
-
column: :promotion_code_batch_id
|
31
|
-
)
|
32
|
-
|
33
|
-
add_index(
|
34
|
-
:spree_promotion_codes,
|
35
|
-
:promotion_code_batch_id
|
36
|
-
)
|
37
|
-
end
|
38
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class CreatePromotionRuleStores < ActiveRecord::Migration[5.1]
|
4
|
-
def change
|
5
|
-
create_table :spree_promotion_rules_stores do |t|
|
6
|
-
t.references :store, null: false
|
7
|
-
t.references :promotion_rule, null: false
|
8
|
-
|
9
|
-
t.timestamps
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'solidus/migrations/promotions_with_code_handlers'
|
4
|
-
|
5
|
-
class RemoveCodeFromSpreePromotions < ActiveRecord::Migration[5.1]
|
6
|
-
class Promotion < ActiveRecord::Base
|
7
|
-
self.table_name = "spree_promotions"
|
8
|
-
self.ignored_columns = %w(type)
|
9
|
-
end
|
10
|
-
|
11
|
-
def up
|
12
|
-
promotions_with_code = Promotion.where.not(code: [nil, ''])
|
13
|
-
|
14
|
-
if promotions_with_code.any?
|
15
|
-
# You have some promotions with "code" field present! This is not good
|
16
|
-
# since we are going to remove that column.
|
17
|
-
#
|
18
|
-
self.class.promotions_with_code_handler.new(self, promotions_with_code).call
|
19
|
-
end
|
20
|
-
|
21
|
-
remove_index :spree_promotions, name: :index_spree_promotions_on_code
|
22
|
-
remove_column :spree_promotions, :code
|
23
|
-
end
|
24
|
-
|
25
|
-
def down
|
26
|
-
add_column :spree_promotions, :code, :string
|
27
|
-
add_index :spree_promotions, :code, name: :index_spree_promotions_on_code
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.promotions_with_code_handler
|
31
|
-
# We propose different approaches, just pick the one that you prefer or
|
32
|
-
# write your custom one.
|
33
|
-
#
|
34
|
-
# The fist one (raising an exception) is the default but you can
|
35
|
-
# comment/uncomment the one then better fits you needs or use a
|
36
|
-
# custom class or callable object.
|
37
|
-
#
|
38
|
-
Solidus::Migrations::PromotionWithCodeHandlers::RaiseException
|
39
|
-
# Solidus::Migrations::PromotionWithCodeHandlers::MoveToSpreePromotionCode
|
40
|
-
# Solidus::Migrations::PromotionWithCodeHandlers::DoNothing
|
41
|
-
end
|
42
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class SetPromotionsWithAnyPolicyToAllIfPossible < ActiveRecord::Migration[5.2]
|
4
|
-
def up
|
5
|
-
Spree::Promotion.where(match_policy: :any).includes(:promotion_rules).all.find_each do |promotion|
|
6
|
-
if promotion.promotion_rules.length <= 1
|
7
|
-
promotion.update!(match_policy: :all)
|
8
|
-
else
|
9
|
-
raise StandardError, <<~MSG
|
10
|
-
You have promotions with a match policy of any and more than one rule. Please
|
11
|
-
run `bundle exec rake solidus:split_promotions_with_any_match_policy`.
|
12
|
-
MSG
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def down
|
18
|
-
# No-Op
|
19
|
-
end
|
20
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class DropUnusedPromoActionLineItems < ActiveRecord::Migration[5.2]
|
2
|
-
def change
|
3
|
-
drop_table :spree_promotion_action_line_items, force: :cascade do |t|
|
4
|
-
t.integer "promotion_action_id"
|
5
|
-
t.integer "variant_id"
|
6
|
-
t.integer "quantity", default: 1
|
7
|
-
t.datetime "created_at", precision: 6
|
8
|
-
t.datetime "updated_at", precision: 6
|
9
|
-
t.index ["promotion_action_id"], name: "index_spree_promotion_action_line_items_on_promotion_action_id"
|
10
|
-
t.index ["variant_id"], name: "index_spree_promotion_action_line_items_on_variant_id"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
class AddOrderPromotionsForeignKey < ActiveRecord::Migration[7.0]
|
2
|
-
def up
|
3
|
-
Spree::OrderPromotion.left_joins(:order).where(spree_orders: { id: nil }).delete_all
|
4
|
-
add_foreign_key :spree_orders_promotions, :spree_orders, column: :order_id, validate: false, on_delete: :cascade
|
5
|
-
end
|
6
|
-
|
7
|
-
def down
|
8
|
-
remove_foreign_key :spree_orders_promotions, :spree_orders
|
9
|
-
end
|
10
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
class AddPromotionOrderPromotionForeignKey < ActiveRecord::Migration[7.0]
|
2
|
-
def up
|
3
|
-
Spree::OrderPromotion.left_joins(:promotion).where(spree_promotions: { id: nil }).delete_all
|
4
|
-
add_foreign_key :spree_orders_promotions, :spree_promotions, column: :promotion_id, on_delete: :cascade
|
5
|
-
end
|
6
|
-
|
7
|
-
def down
|
8
|
-
remove_foreign_key :spree_orders_promotions, :spree_promotions
|
9
|
-
end
|
10
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Solidus
|
4
|
-
module Migrations
|
5
|
-
module PromotionWithCodeHandlers
|
6
|
-
class PromotionCode < Spree::Base
|
7
|
-
self.table_name = "spree_promotion_codes"
|
8
|
-
end
|
9
|
-
|
10
|
-
class Base
|
11
|
-
attr_reader :migration_context, :promotions
|
12
|
-
|
13
|
-
def initialize(migration_context, promotions)
|
14
|
-
@migration_context = migration_context
|
15
|
-
@promotions = promotions
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class RaiseException < Base
|
20
|
-
def call
|
21
|
-
# Please note that this will block the current migration and rollback all
|
22
|
-
# the previous ones run with the same "rails db:migrate" command.
|
23
|
-
#
|
24
|
-
raise StandardError, "You are trying to drop 'code' column from "\
|
25
|
-
"spree_promotions table but you have at least one record with that "\
|
26
|
-
"column filled. Please take care of that or you could lose data. See:" \
|
27
|
-
"\n" \
|
28
|
-
"https://github.com/solidusio/solidus/pull/3028"\
|
29
|
-
"\n"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class MoveToSpreePromotionCode < Base
|
34
|
-
def call
|
35
|
-
# This is another possible approach, it will convert Spree::Promotion#code
|
36
|
-
# to a Spree::PromotionCode before removing the `code` field.
|
37
|
-
#
|
38
|
-
# NOTE: promotion codes will be downcased and stripped
|
39
|
-
promotions.find_each do |promotion|
|
40
|
-
normalized_code = promotion.code.downcase.strip
|
41
|
-
|
42
|
-
PromotionCode.find_or_create_by!(
|
43
|
-
value: normalized_code,
|
44
|
-
promotion_id: promotion.id
|
45
|
-
) do
|
46
|
-
migration_context.say "Creating Spree::PromotionCode with value "\
|
47
|
-
"'#{normalized_code}' for Spree::Promotion with id '#{promotion.id}'"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class DoNothing < Base
|
54
|
-
def call
|
55
|
-
# This approach will delete all codes without taking any action. At
|
56
|
-
# least we could print a message to track what we are deleting.
|
57
|
-
#
|
58
|
-
promotions.find_each do |promotion|
|
59
|
-
migration_context.say "Code '#{promotion.code}' is going to be removed "\
|
60
|
-
"from Spree::Promotion with id '#{promotion.id}'"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
module PermissionSets
|
5
|
-
# Read-only permissions for promotions.
|
6
|
-
#
|
7
|
-
# This permission set allows users to view all related information about
|
8
|
-
# promotions, also from the admin panel, including:
|
9
|
-
#
|
10
|
-
# - Promotions
|
11
|
-
# - Promotion rules
|
12
|
-
# - Promotion actions
|
13
|
-
# - Promotion categories
|
14
|
-
# - Promotion codes
|
15
|
-
class PromotionDisplay < PermissionSets::Base
|
16
|
-
def activate!
|
17
|
-
can [:read, :admin, :edit], Spree::Promotion
|
18
|
-
can [:read, :admin], Spree::PromotionRule
|
19
|
-
can [:read, :admin], Spree::PromotionAction
|
20
|
-
can [:read, :admin], Spree::PromotionCategory
|
21
|
-
can [:read, :admin], Spree::PromotionCode
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Spree
|
4
|
-
module PermissionSets
|
5
|
-
# Full permissions for promotion management.
|
6
|
-
#
|
7
|
-
# This permission set grants full control over all promotion and related resources,
|
8
|
-
# including:
|
9
|
-
#
|
10
|
-
# - Promotions
|
11
|
-
# - Promotion rules
|
12
|
-
# - Promotion actions
|
13
|
-
# - Promotion categories
|
14
|
-
# - Promotion codes
|
15
|
-
class PromotionManagement < PermissionSets::Base
|
16
|
-
def activate!
|
17
|
-
can :manage, Spree::Promotion
|
18
|
-
can :manage, Spree::PromotionRule
|
19
|
-
can :manage, Spree::PromotionAction
|
20
|
-
can :manage, Spree::PromotionCategory
|
21
|
-
can :manage, Spree::PromotionCode
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "ransack/version"
|
4
|
-
|
5
|
-
return unless Ransack::VERSION.start_with?("4.1.")
|
6
|
-
|
7
|
-
module RansackNodeConditionPatch
|
8
|
-
private
|
9
|
-
|
10
|
-
# Waiting for https://github.com/activerecord-hackery/ransack/pull/1468
|
11
|
-
def casted_array?(predicate)
|
12
|
-
predicate.is_a?(Arel::Nodes::Casted) && predicate.value.is_a?(Array)
|
13
|
-
end
|
14
|
-
|
15
|
-
Ransack::Nodes::Condition.prepend(self)
|
16
|
-
end
|