solidus_friendly_promotions 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +61 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +1 -0
- data/.github_changelog_generator +2 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.rubocop.yml +29 -0
- data/.rubocop_todo.yml +157 -0
- data/.standard.yml +4 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +42 -0
- data/LICENSE +26 -0
- data/MIGRATING.md +134 -0
- data/README.md +144 -0
- data/Rakefile +7 -0
- data/app/assets/config/solidus_friendly_promotions/manifest.js +7 -0
- data/app/controllers/solidus_friendly_promotions/admin/base_controller.rb +54 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotion_actions_controller.rb +103 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotion_categories_controller.rb +13 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotion_code_batches_controller.rb +30 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotion_codes_controller.rb +58 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotion_rules_controller.rb +105 -0
- data/app/controllers/solidus_friendly_promotions/admin/promotions_controller.rb +64 -0
- data/app/decorators/models/solidus_friendly_promotions/adjustment_decorator.rb +26 -0
- data/app/decorators/models/solidus_friendly_promotions/line_item_decorator.rb +7 -0
- data/app/decorators/models/solidus_friendly_promotions/order_decorator.rb +42 -0
- data/app/decorators/models/solidus_friendly_promotions/order_recalculator_decorator.rb +13 -0
- data/app/decorators/models/solidus_friendly_promotions/shipment_decorator.rb +14 -0
- data/app/decorators/models/solidus_friendly_promotions/shipping_rate_decorator.rb +29 -0
- data/app/helpers/solidus_friendly_promotions/admin/promotion_actions_helper.rb +23 -0
- data/app/helpers/solidus_friendly_promotions/admin/promotion_rules_helper.rb +25 -0
- data/app/javascript/solidus_friendly_promotions/controllers/application.js +9 -0
- data/app/javascript/solidus_friendly_promotions/controllers/calculator_tiers_controller.js +37 -0
- data/app/javascript/solidus_friendly_promotions/controllers/flash_controller.js +10 -0
- data/app/javascript/solidus_friendly_promotions/controllers/index.js +8 -0
- data/app/javascript/solidus_friendly_promotions/controllers/product_option_values_controller.js +62 -0
- data/app/javascript/solidus_friendly_promotions/jquery/option_value_picker.js +44 -0
- data/app/javascript/solidus_friendly_promotions.js +12 -0
- data/app/jobs/solidus_friendly_promotions/promotion_code_batch_job.rb +26 -0
- data/app/mailers/solidus_friendly_promotions/promotion_code_batch_mailer.rb +15 -0
- data/app/models/concerns/solidus_friendly_promotions/discountable_amount.rb +21 -0
- data/app/models/concerns/solidus_friendly_promotions/rules/line_item_applicable_order_rule.rb +23 -0
- data/app/models/concerns/solidus_friendly_promotions/rules/line_item_level_rule.rb +15 -0
- data/app/models/concerns/solidus_friendly_promotions/rules/order_level_rule.rb +15 -0
- data/app/models/concerns/solidus_friendly_promotions/rules/shipment_level_rule.rb +15 -0
- data/app/models/solidus_friendly_promotions/actions/adjust_line_item.rb +15 -0
- data/app/models/solidus_friendly_promotions/actions/adjust_line_item_quantity_groups.rb +116 -0
- data/app/models/solidus_friendly_promotions/actions/adjust_shipment.rb +15 -0
- data/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb +37 -0
- data/app/models/solidus_friendly_promotions/calculators/flat_rate.rb +21 -0
- data/app/models/solidus_friendly_promotions/calculators/flexi_rate.rb +24 -0
- data/app/models/solidus_friendly_promotions/calculators/percent.rb +17 -0
- data/app/models/solidus_friendly_promotions/calculators/tiered_flat_rate.rb +56 -0
- data/app/models/solidus_friendly_promotions/calculators/tiered_percent.rb +66 -0
- data/app/models/solidus_friendly_promotions/distributed_amounts_handler.rb +43 -0
- data/app/models/solidus_friendly_promotions/eligibility_result.rb +5 -0
- data/app/models/solidus_friendly_promotions/eligibility_results.rb +48 -0
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/choose_discounts.rb +21 -0
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/discount_order.rb +76 -0
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/load_promotions.rb +54 -0
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/persist_discounted_order.rb +81 -0
- data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster.rb +25 -0
- data/app/models/solidus_friendly_promotions/item_discount.rb +21 -0
- data/app/models/solidus_friendly_promotions/migration_support/order_promotion_syncer.rb +54 -0
- data/app/models/solidus_friendly_promotions/order_promotion.rb +23 -0
- data/app/models/solidus_friendly_promotions/permission_sets/friendly_promotion_management.rb +15 -0
- data/app/models/solidus_friendly_promotions/products_promotion_rule.rb +8 -0
- data/app/models/solidus_friendly_promotions/promotion.rb +166 -0
- data/app/models/solidus_friendly_promotions/promotion_action.rb +73 -0
- data/app/models/solidus_friendly_promotions/promotion_category.rb +9 -0
- data/app/models/solidus_friendly_promotions/promotion_code/batch_builder.rb +72 -0
- data/app/models/solidus_friendly_promotions/promotion_code.rb +55 -0
- data/app/models/solidus_friendly_promotions/promotion_code_batch.rb +25 -0
- data/app/models/solidus_friendly_promotions/promotion_handler/coupon.rb +113 -0
- data/app/models/solidus_friendly_promotions/promotion_handler/page.rb +30 -0
- data/app/models/solidus_friendly_promotions/promotion_rule.rb +55 -0
- data/app/models/solidus_friendly_promotions/promotion_rules_store.rb +8 -0
- data/app/models/solidus_friendly_promotions/promotion_rules_taxon.rb +8 -0
- data/app/models/solidus_friendly_promotions/promotion_rules_user.rb +8 -0
- data/app/models/solidus_friendly_promotions/rules/discounted_item_total.rb +22 -0
- data/app/models/solidus_friendly_promotions/rules/first_order.rb +31 -0
- data/app/models/solidus_friendly_promotions/rules/first_repeat_purchase_since.rb +31 -0
- data/app/models/solidus_friendly_promotions/rules/item_total.rb +86 -0
- data/app/models/solidus_friendly_promotions/rules/line_item_option_value.rb +37 -0
- data/app/models/solidus_friendly_promotions/rules/line_item_product.rb +52 -0
- data/app/models/solidus_friendly_promotions/rules/line_item_taxon.rb +55 -0
- data/app/models/solidus_friendly_promotions/rules/minimum_quantity.rb +48 -0
- data/app/models/solidus_friendly_promotions/rules/nth_order.rb +40 -0
- data/app/models/solidus_friendly_promotions/rules/one_use_per_user.rb +25 -0
- data/app/models/solidus_friendly_promotions/rules/option_value.rb +28 -0
- data/app/models/solidus_friendly_promotions/rules/product.rb +85 -0
- data/app/models/solidus_friendly_promotions/rules/shipping_method.rb +19 -0
- data/app/models/solidus_friendly_promotions/rules/store.rb +26 -0
- data/app/models/solidus_friendly_promotions/rules/taxon.rb +98 -0
- data/app/models/solidus_friendly_promotions/rules/user.rb +35 -0
- data/app/models/solidus_friendly_promotions/rules/user_logged_in.rb +16 -0
- data/app/models/solidus_friendly_promotions/rules/user_role.rb +42 -0
- data/app/models/solidus_friendly_promotions/shipping_rate_discount.rb +11 -0
- data/app/models/solidus_friendly_promotions/simple_order_contents.rb +27 -0
- data/app/models/solidus_friendly_promotions.rb +7 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_calculator_select.html.erb +16 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_form.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_promotion_action.html.erb +29 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/_type_select.html.erb +14 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_line_item.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_line_item_quantity_groups.html.erb +13 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_shipment.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_calculator_fields.erb +8 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/_default_fields.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/distributed_amount/_fields.html.erb +56 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/flat_rate/_fields.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_flat_rate/_fields.html.erb +34 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_flat_rate/_tier_fields.html.erb +32 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_percent/_fields.html.erb +34 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_percent/_tier_fields.html.erb +32 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/edit.html.erb +23 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_actions/new.html.erb +26 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_categories/_form.html.erb +14 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_categories/edit.html.erb +10 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_categories/index.html.erb +47 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_categories/new.html.erb +10 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_codes/index.csv.ruby +8 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_codes/index.html.erb +32 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_codes/new.html.erb +31 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/_promotion_rule.html.erb +22 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/_type_select.html.erb +20 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/new.html.erb +24 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_first_order.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_first_repeat_purchase_since.html.erb +6 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_item_total.html.erb +17 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_option_value.html.erb +25 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_product.html.erb +21 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_taxon.html.erb +17 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_minimum_quantity.html.erb +5 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_nth_order.html.erb +15 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_one_use_per_user.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_option_value.html.erb +63 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_product.html.erb +44 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_shipping_method.html.erb +10 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_store.html.erb +9 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_taxon.html.erb +44 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user.html.erb +7 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user_logged_in.html.erb +3 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user_role.html.erb +15 -0
- data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/line_item_option_value/_option_value_fields.html.erb +17 -0
- data/app/views/solidus_friendly_promotions/admin/promotions/_activations_edit.html.erb +22 -0
- data/app/views/solidus_friendly_promotions/admin/promotions/_activations_new.html.erb +43 -0
- data/app/views/solidus_friendly_promotions/admin/promotions/_form.html.erb +96 -0
- data/app/views/solidus_friendly_promotions/admin/promotions/edit.html.erb +73 -0
- data/app/views/solidus_friendly_promotions/admin/promotions/index.html.erb +124 -0
- data/app/views/solidus_friendly_promotions/admin/promotions/new.html.erb +9 -0
- data/app/views/solidus_friendly_promotions/admin/shared/_promotion_sub_menu.html.erb +14 -0
- data/app/views/solidus_friendly_promotions/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
- data/app/views/solidus_friendly_promotions/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
- data/bin/console +17 -0
- data/bin/importmap +4 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/sandbox +75 -0
- data/bin/setup +8 -0
- data/config/importmap.rb +12 -0
- data/config/initializers/solidus_friendly_promotions.rb +3 -0
- data/config/locales/en.yml +255 -0
- data/config/routes.rb +18 -0
- data/db/migrate/20230703101637_create_promotions.rb +16 -0
- data/db/migrate/20230703141116_create_promotion_categories.rb +14 -0
- data/db/migrate/20230703143943_create_promotion_rules.rb +12 -0
- data/db/migrate/20230704083830_add_rule_tables.rb +31 -0
- data/db/migrate/20230704093625_create_promotion_actions.rb +14 -0
- data/db/migrate/20230704102444_create_promotion_codes.rb +11 -0
- data/db/migrate/20230704102656_create_promotion_code_batches.rb +33 -0
- data/db/migrate/20230705171556_create_friendly_order_promotions.rb +11 -0
- data/db/migrate/20230725074235_create_shipping_rate_discounts.rb +12 -0
- data/db/migrate/20230928093138_add_lane_to_solidus_friendly_promotions_promotions.rb +5 -0
- data/db/migrate/20231006134042_add_customer_label_to_promotions.rb +7 -0
- data/db/migrate/20231011100059_add_db_comments_to_friendly_order_promotions.rb +61 -0
- data/db/migrate/20231011120928_add_db_comments_to_friendly_promotion_rules_taxons.rb +54 -0
- data/db/migrate/20231011131324_add_db_comments_to_friendly_promotion_rules.rb +60 -0
- data/db/migrate/20231011142040_add_db_comments_to_friendly_promotion_rules_users.rb +53 -0
- data/db/migrate/20231011154553_allow_null_promotion_ids.rb +9 -0
- data/db/migrate/20231011155822_add_db_comments_to_friendly_promotions.rb +123 -0
- data/db/migrate/20231011163030_add_db_comments_to_friendly_promotion_codes.rb +60 -0
- data/db/migrate/20231011173312_add_db_comments_to_friendly_promotion_code_batches.rb +91 -0
- data/db/migrate/20231011184205_add_db_comments_to_friendly_promotion_rules_stores.rb +53 -0
- data/db/migrate/20231011190222_add_db_comments_to_friendly_promotion_actions.rb +68 -0
- data/db/migrate/20231012020928_add_db_comments_to_friendly_products_promotion_rules.rb +52 -0
- data/db/migrate/20231012120928_add_db_comments_to_friendly_promotion_categories.rb +52 -0
- data/db/migrate/20231013181921_add_original_promotion_ids.rb +6 -0
- data/lib/generators/solidus_friendly_promotions/install/install_generator.rb +38 -0
- data/lib/generators/solidus_friendly_promotions/install/templates/initializer.rb +118 -0
- data/lib/solidus_friendly_promotions/configuration.rb +52 -0
- data/lib/solidus_friendly_promotions/engine.rb +37 -0
- data/lib/solidus_friendly_promotions/migrate_adjustments.rb +62 -0
- data/lib/solidus_friendly_promotions/migrate_order_promotions.rb +73 -0
- data/lib/solidus_friendly_promotions/nested_class_set.rb +24 -0
- data/lib/solidus_friendly_promotions/promotion_map.rb +96 -0
- data/lib/solidus_friendly_promotions/promotion_migrator.rb +103 -0
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_order_factory.rb +20 -0
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_order_promotion_factory.rb +8 -0
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_category_factory.rb +7 -0
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_code_factory.rb +8 -0
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_factory.rb +91 -0
- data/lib/solidus_friendly_promotions/testing_support/factories/friendly_shipping_rate_discount_factory.rb +14 -0
- data/lib/solidus_friendly_promotions/testing_support.rb +9 -0
- data/lib/solidus_friendly_promotions/version.rb +5 -0
- data/lib/solidus_friendly_promotions.rb +18 -0
- data/lib/tasks/solidus_friendly_promotions/migrate_adjustments.rake +17 -0
- data/lib/tasks/solidus_friendly_promotions/migrate_existing_promotions.rake +12 -0
- data/lib/tasks/solidus_friendly_promotions/migrate_order_promotions.rake +17 -0
- data/solidus_friendly_promotions.gemspec +40 -0
- metadata +392 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddDbCommentsToFriendlyPromotionCategories < ActiveRecord::Migration[6.1]
|
4
|
+
def up
|
5
|
+
if connection.supports_comments?
|
6
|
+
change_table_comment(:friendly_promotion_categories, friendly_promotion_categories_table_comment)
|
7
|
+
change_column_comment(:friendly_promotion_categories, :id, id_comment)
|
8
|
+
change_column_comment(:friendly_promotion_categories, :name, name_comment)
|
9
|
+
change_column_comment(:friendly_promotion_categories, :code, code_comment)
|
10
|
+
change_column_comment(:friendly_promotion_categories, :created_at, created_at_comment)
|
11
|
+
change_column_comment(:friendly_promotion_categories, :updated_at, updated_at_comment)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def friendly_promotion_categories_table_comment
|
18
|
+
<<~COMMENT
|
19
|
+
Category that helps admins index promotions.
|
20
|
+
COMMENT
|
21
|
+
end
|
22
|
+
|
23
|
+
def id_comment
|
24
|
+
<<~COMMENT
|
25
|
+
Primary key of this table.
|
26
|
+
COMMENT
|
27
|
+
end
|
28
|
+
|
29
|
+
def name_comment
|
30
|
+
<<~COMMENT
|
31
|
+
Name of this promotion category.
|
32
|
+
COMMENT
|
33
|
+
end
|
34
|
+
|
35
|
+
def code_comment
|
36
|
+
<<~COMMENT
|
37
|
+
Code of this promotion category.
|
38
|
+
COMMENT
|
39
|
+
end
|
40
|
+
|
41
|
+
def created_at_comment
|
42
|
+
<<~COMMENT
|
43
|
+
Timestamp indicating when this record was created.
|
44
|
+
COMMENT
|
45
|
+
end
|
46
|
+
|
47
|
+
def updated_at_comment
|
48
|
+
<<~COMMENT
|
49
|
+
Timestamp indicating when this record was last updated.
|
50
|
+
COMMENT
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class AddOriginalPromotionIds < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
add_reference :friendly_promotions, :original_promotion, type: :integer, index: {name: :index_original_promotion_id}, foreign_key: {to_table: :spree_promotions}
|
4
|
+
add_reference :friendly_promotion_actions, :original_promotion_action, type: :integer, index: {name: :index_original_promotion_action_id}, foreign_key: {to_table: :spree_promotion_actions}
|
5
|
+
end
|
6
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
class_option :auto_run_migrations, type: :boolean, default: false
|
7
|
+
source_root File.expand_path("templates", __dir__)
|
8
|
+
|
9
|
+
def self.exit_on_failure?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy_initializer
|
14
|
+
template "initializer.rb", "config/initializers/solidus_friendly_promotions.rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_migrations
|
18
|
+
run "bin/rails railties:install:migrations FROM=solidus_friendly_promotions"
|
19
|
+
end
|
20
|
+
|
21
|
+
def mount_engine
|
22
|
+
inject_into_file "config/routes.rb",
|
23
|
+
" mount SolidusFriendlyPromotions::Engine => '/'\n",
|
24
|
+
before: / mount Spree::Core::Engine.*/,
|
25
|
+
verbose: true
|
26
|
+
end
|
27
|
+
|
28
|
+
def run_migrations
|
29
|
+
run_migrations = options[:auto_run_migrations] || ["", "y", "Y"].include?(ask("Would you like to run the migrations now? [Y/n]")) # rubocop:disable Layout/LineLength
|
30
|
+
if run_migrations
|
31
|
+
run "bin/rails db:migrate"
|
32
|
+
else
|
33
|
+
puts "Skipping bin/rails db:migrate, don't forget to run it!" # rubocop:disable Rails/Output
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Replace solidus core's order contents and promotion adjuster classes with ours.
|
4
|
+
Spree::Config.order_contents_class = "SolidusFriendlyPromotions::SimpleOrderContents"
|
5
|
+
Spree::Config.promotion_adjuster_class = "SolidusFriendlyPromotions::FriendlyPromotionAdjuster"
|
6
|
+
|
7
|
+
# Replace the promotions menu from core with ours
|
8
|
+
Spree::Backend::Config.configure do |config|
|
9
|
+
config.menu_items = config.menu_items.map do |item|
|
10
|
+
next item unless item.label.to_sym == :promotions
|
11
|
+
|
12
|
+
# The API of the MenuItem class changes in Solidus 4.2.0
|
13
|
+
if item.respond_to?(:children)
|
14
|
+
Spree::BackendConfiguration::MenuItem.new(
|
15
|
+
label: :promotions,
|
16
|
+
icon: "bullhorn",
|
17
|
+
condition: -> { can?(:admin, SolidusFriendlyPromotions::Promotion) },
|
18
|
+
url: -> { SolidusFriendlyPromotions::Engine.routes.url_helpers.admin_promotions_path },
|
19
|
+
data_hook: :admin_promotion_sub_tabs,
|
20
|
+
children: [
|
21
|
+
Spree::BackendConfiguration::MenuItem.new(
|
22
|
+
label: :promotions,
|
23
|
+
url: -> { SolidusFriendlyPromotions::Engine.routes.url_helpers.admin_promotions_path },
|
24
|
+
condition: -> { can?(:admin, SolidusFriendlyPromotions::Promotion) }
|
25
|
+
),
|
26
|
+
Spree::BackendConfiguration::MenuItem.new(
|
27
|
+
label: :promotion_categories,
|
28
|
+
url: -> { SolidusFriendlyPromotions::Engine.routes.url_helpers.admin_promotion_categories_path },
|
29
|
+
condition: -> { can?(:admin, SolidusFriendlyPromotions::PromotionCategory) }
|
30
|
+
),
|
31
|
+
Spree::BackendConfiguration::MenuItem.new(
|
32
|
+
label: :legacy_promotions,
|
33
|
+
condition: -> { can?(:admin, Spree::Promotion && Spree::Promotion.any?) },
|
34
|
+
url: -> { Spree::Core::Engine.routes.url_helpers.admin_promotions_path },
|
35
|
+
match_path: "/admin/promotions/"
|
36
|
+
),
|
37
|
+
Spree::BackendConfiguration::MenuItem.new(
|
38
|
+
label: :legacy_promotion_categories,
|
39
|
+
condition: -> { can?(:admin, Spree::PromotionCategory && Spree::Promotion.any?) },
|
40
|
+
url: -> { Spree::Core::Engine.routes.url_helpers.admin_promotion_categories_path },
|
41
|
+
match_path: "/admin/promotion_categories/"
|
42
|
+
)
|
43
|
+
]
|
44
|
+
)
|
45
|
+
else
|
46
|
+
Spree::BackendConfiguration::MenuItem.new(
|
47
|
+
[:promotions, :promotion_categories],
|
48
|
+
"bullhorn",
|
49
|
+
partial: "solidus_friendly_promotions/admin/shared/promotion_sub_menu",
|
50
|
+
condition: -> { can?(:admin, SolidusFriendlyPromotions::Promotion) },
|
51
|
+
url: -> { SolidusFriendlyPromotions::Engine.routes.url_helpers.admin_promotions_path },
|
52
|
+
position: 2
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
SolidusFriendlyPromotions.configure do |config|
|
59
|
+
# This class chooses which promotion should apply to a line item in case
|
60
|
+
# that more than one promotion is eligible.
|
61
|
+
config.discount_chooser_class = "SolidusFriendlyPromotions::FriendlyPromotionAdjuster::ChooseDiscounts"
|
62
|
+
|
63
|
+
# How many promotions should be displayed on the index page in the admin.
|
64
|
+
config.promotions_per_page = 25
|
65
|
+
|
66
|
+
config.promotion_calculators = SolidusFriendlyPromotions::NestedClassSet.new(
|
67
|
+
"SolidusFriendlyPromotions::Actions::AdjustShipment" => [
|
68
|
+
"SolidusFriendlyPromotions::Calculators::FlatRate",
|
69
|
+
"SolidusFriendlyPromotions::Calculators::FlexiRate",
|
70
|
+
"SolidusFriendlyPromotions::Calculators::Percent",
|
71
|
+
"SolidusFriendlyPromotions::Calculators::TieredFlatRate",
|
72
|
+
"SolidusFriendlyPromotions::Calculators::TieredPercent"
|
73
|
+
],
|
74
|
+
"SolidusFriendlyPromotions::Actions::AdjustLineItem" => [
|
75
|
+
"SolidusFriendlyPromotions::Calculators::DistributedAmount",
|
76
|
+
"SolidusFriendlyPromotions::Calculators::FlatRate",
|
77
|
+
"SolidusFriendlyPromotions::Calculators::FlexiRate",
|
78
|
+
"SolidusFriendlyPromotions::Calculators::Percent",
|
79
|
+
"SolidusFriendlyPromotions::Calculators::TieredFlatRate",
|
80
|
+
"SolidusFriendlyPromotions::Calculators::TieredPercent"
|
81
|
+
],
|
82
|
+
"SolidusFriendlyPromotions::Actions::AdjustLineItemQuantityGroups" => [
|
83
|
+
"SolidusFriendlyPromotions::Calculators::FlatRate",
|
84
|
+
"SolidusFriendlyPromotions::Calculators::Percent"
|
85
|
+
]
|
86
|
+
)
|
87
|
+
|
88
|
+
config.order_rules = [
|
89
|
+
"SolidusFriendlyPromotions::Rules::FirstOrder",
|
90
|
+
"SolidusFriendlyPromotions::Rules::FirstRepeatPurchaseSince",
|
91
|
+
"SolidusFriendlyPromotions::Rules::ItemTotal",
|
92
|
+
"SolidusFriendlyPromotions::Rules::DiscountedItemTotal",
|
93
|
+
"SolidusFriendlyPromotions::Rules::MinimumQuantity",
|
94
|
+
"SolidusFriendlyPromotions::Rules::NthOrder",
|
95
|
+
"SolidusFriendlyPromotions::Rules::OneUsePerUser",
|
96
|
+
"SolidusFriendlyPromotions::Rules::OptionValue",
|
97
|
+
"SolidusFriendlyPromotions::Rules::Product",
|
98
|
+
"SolidusFriendlyPromotions::Rules::Store",
|
99
|
+
"SolidusFriendlyPromotions::Rules::Taxon",
|
100
|
+
"SolidusFriendlyPromotions::Rules::UserLoggedIn",
|
101
|
+
"SolidusFriendlyPromotions::Rules::UserRole",
|
102
|
+
"SolidusFriendlyPromotions::Rules::User"
|
103
|
+
]
|
104
|
+
config.line_item_rules = [
|
105
|
+
"SolidusFriendlyPromotions::Rules::LineItemOptionValue",
|
106
|
+
"SolidusFriendlyPromotions::Rules::LineItemProduct",
|
107
|
+
"SolidusFriendlyPromotions::Rules::LineItemTaxon"
|
108
|
+
]
|
109
|
+
config.shipment_rules = [
|
110
|
+
"SolidusFriendlyPromotions::Rules::ShippingMethod"
|
111
|
+
]
|
112
|
+
|
113
|
+
config.actions = [
|
114
|
+
"SolidusFriendlyPromotions::Actions::AdjustLineItem",
|
115
|
+
"SolidusFriendlyPromotions::Actions::AdjustLineItemQuantityGroups",
|
116
|
+
"SolidusFriendlyPromotions::Actions::AdjustShipment"
|
117
|
+
]
|
118
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spree/core/environment_extension"
|
4
|
+
|
5
|
+
module SolidusFriendlyPromotions
|
6
|
+
class Configuration < Spree::Preferences::Configuration
|
7
|
+
attr_accessor :sync_order_promotions
|
8
|
+
attr_accessor :promotion_calculators
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@sync_order_promotions = true
|
12
|
+
@promotion_calculators = NestedClassSet.new
|
13
|
+
end
|
14
|
+
|
15
|
+
include Spree::Core::EnvironmentExtension
|
16
|
+
|
17
|
+
add_class_set :line_item_discount_calculators
|
18
|
+
add_class_set :shipment_discount_calculators
|
19
|
+
|
20
|
+
add_class_set :order_rules
|
21
|
+
add_class_set :line_item_rules
|
22
|
+
add_class_set :shipment_rules
|
23
|
+
|
24
|
+
add_class_set :actions
|
25
|
+
|
26
|
+
class_name_attribute :discount_chooser_class, default: "SolidusFriendlyPromotions::DiscountChooser"
|
27
|
+
class_name_attribute :promotion_code_batch_mailer_class,
|
28
|
+
default: "SolidusFriendlyPromotions::PromotionCodeBatchMailer"
|
29
|
+
|
30
|
+
# @!attribute [rw] promotions_per_page
|
31
|
+
# @return [Integer] Promotions to show per-page in the admin (default: +25+)
|
32
|
+
preference :promotions_per_page, :integer, default: 25
|
33
|
+
|
34
|
+
preference :lanes, :hash, default: {
|
35
|
+
pre: 0,
|
36
|
+
default: 1,
|
37
|
+
post: 2
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
class << self
|
42
|
+
def configuration
|
43
|
+
@configuration ||= Configuration.new
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :config, :configuration
|
47
|
+
|
48
|
+
def configure
|
49
|
+
yield configuration
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "solidus_core"
|
4
|
+
require "solidus_support"
|
5
|
+
|
6
|
+
module SolidusFriendlyPromotions
|
7
|
+
class Engine < Rails::Engine
|
8
|
+
include SolidusSupport::EngineExtensions
|
9
|
+
|
10
|
+
isolate_namespace ::SolidusFriendlyPromotions
|
11
|
+
|
12
|
+
engine_name "solidus_friendly_promotions"
|
13
|
+
|
14
|
+
# use rspec for tests
|
15
|
+
config.generators do |g|
|
16
|
+
g.test_framework :rspec
|
17
|
+
end
|
18
|
+
|
19
|
+
initializer "solidus_friendly_promotions.assets" do |app|
|
20
|
+
app.config.assets.precompile << "solidus_friendly_promotions/manifest.js"
|
21
|
+
end
|
22
|
+
|
23
|
+
initializer "solidus_friendly_promotions.importmap" do |app|
|
24
|
+
SolidusFriendlyPromotions.importmap.draw(Engine.root.join("config", "importmap.rb"))
|
25
|
+
|
26
|
+
package_path = Engine.root.join("app/javascript")
|
27
|
+
app.config.assets.paths << package_path
|
28
|
+
|
29
|
+
if app.config.importmap.sweep_cache
|
30
|
+
SolidusFriendlyPromotions.importmap.cache_sweeper(watches: package_path)
|
31
|
+
ActiveSupport.on_load(:action_controller_base) do
|
32
|
+
before_action { SolidusFriendlyPromotions.importmap.cache_sweeper.execute_if_updated }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
class MigrateAdjustments
|
5
|
+
class << self
|
6
|
+
def up
|
7
|
+
sql = if ActiveRecord::Base.connection_db_config.adapter == "mysql2"
|
8
|
+
<<~SQL
|
9
|
+
UPDATE spree_adjustments
|
10
|
+
INNER JOIN spree_promotion_actions ON spree_adjustments.source_id = spree_promotion_actions.id and spree_adjustments.source_type = 'Spree::PromotionAction'
|
11
|
+
INNER JOIN friendly_promotion_actions ON friendly_promotion_actions.original_promotion_action_id = spree_promotion_actions.id
|
12
|
+
SET source_id = friendly_promotion_actions.id,
|
13
|
+
source_type = 'SolidusFriendlyPromotions::PromotionAction'
|
14
|
+
SQL
|
15
|
+
else
|
16
|
+
<<~SQL
|
17
|
+
UPDATE spree_adjustments
|
18
|
+
SET source_id = friendly_promotion_actions.id,
|
19
|
+
source_type = 'SolidusFriendlyPromotions::PromotionAction'
|
20
|
+
FROM spree_promotion_actions
|
21
|
+
INNER JOIN friendly_promotion_actions ON friendly_promotion_actions.original_promotion_action_id = spree_promotion_actions.id
|
22
|
+
WHERE spree_adjustments.source_id = spree_promotion_actions.id and spree_adjustments.source_type = 'Spree::PromotionAction'
|
23
|
+
SQL
|
24
|
+
end
|
25
|
+
|
26
|
+
execute(sql)
|
27
|
+
end
|
28
|
+
|
29
|
+
def down
|
30
|
+
sql = if ActiveRecord::Base.connection_db_config.adapter == "mysql2"
|
31
|
+
<<~SQL
|
32
|
+
UPDATE spree_adjustments
|
33
|
+
INNER JOIN friendly_promotion_actions
|
34
|
+
INNER JOIN spree_promotion_actions ON spree_adjustments.source_id = friendly_promotion_actions.id and spree_adjustments.source_type = 'SolidusFriendlyPromotions::PromotionAction'
|
35
|
+
SET source_id = spree_promotion_actions.id,
|
36
|
+
source_type = 'Spree::PromotionAction'
|
37
|
+
WHERE friendly_promotion_actions.original_promotion_action_id = spree_promotion_actions.id
|
38
|
+
SQL
|
39
|
+
else
|
40
|
+
<<~SQL
|
41
|
+
UPDATE spree_adjustments
|
42
|
+
SET source_id = spree_promotion_actions.id,
|
43
|
+
source_type = 'Spree::PromotionAction'
|
44
|
+
FROM spree_promotion_actions
|
45
|
+
INNER JOIN friendly_promotion_actions ON friendly_promotion_actions.original_promotion_action_id = spree_promotion_actions.id
|
46
|
+
WHERE spree_adjustments.source_id = friendly_promotion_actions.id and spree_adjustments.source_type = 'SolidusFriendlyPromotions::PromotionAction'
|
47
|
+
SQL
|
48
|
+
end
|
49
|
+
|
50
|
+
execute(sql)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def execute(sql)
|
56
|
+
Spree::Adjustment.transaction do
|
57
|
+
ActiveRecord::Base.connection.execute(sql)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
class MigrateOrderPromotions
|
5
|
+
class << self
|
6
|
+
def up
|
7
|
+
sql = <<~SQL
|
8
|
+
INSERT INTO friendly_order_promotions (
|
9
|
+
order_id,
|
10
|
+
promotion_id,
|
11
|
+
promotion_code_id,
|
12
|
+
created_at,
|
13
|
+
updated_at
|
14
|
+
)
|
15
|
+
SELECT
|
16
|
+
spree_orders_promotions.order_id AS order_id,
|
17
|
+
friendly_promotions.id AS promotion_id,
|
18
|
+
friendly_promotion_codes.id AS promotion_code_id,
|
19
|
+
spree_orders_promotions.created_at,
|
20
|
+
spree_orders_promotions.updated_at
|
21
|
+
FROM spree_orders_promotions
|
22
|
+
INNER JOIN spree_promotions ON spree_orders_promotions.promotion_id = spree_promotions.id
|
23
|
+
INNER JOIN friendly_promotions ON spree_promotions.id = friendly_promotions.original_promotion_id
|
24
|
+
LEFT OUTER JOIN spree_promotion_codes ON spree_orders_promotions.promotion_code_id = spree_promotion_codes.id
|
25
|
+
LEFT OUTER JOIN friendly_promotion_codes ON spree_promotion_codes.value = friendly_promotion_codes.value
|
26
|
+
WHERE NOT EXISTS (
|
27
|
+
SELECT NULL
|
28
|
+
FROM friendly_order_promotions
|
29
|
+
WHERE friendly_order_promotions.order_id = order_id
|
30
|
+
AND (friendly_order_promotions.promotion_code_id = promotion_code_id OR promotion_code_id IS NULL)
|
31
|
+
AND friendly_order_promotions.promotion_id = promotion_id
|
32
|
+
);
|
33
|
+
SQL
|
34
|
+
ActiveRecord::Base.connection.execute(sql)
|
35
|
+
|
36
|
+
Spree::OrderPromotion.delete_all
|
37
|
+
end
|
38
|
+
|
39
|
+
def down
|
40
|
+
sql = <<~SQL
|
41
|
+
INSERT INTO spree_orders_promotions (
|
42
|
+
order_id,
|
43
|
+
promotion_id,
|
44
|
+
promotion_code_id,
|
45
|
+
created_at,
|
46
|
+
updated_at
|
47
|
+
)
|
48
|
+
SELECT
|
49
|
+
friendly_order_promotions.order_id AS order_id,
|
50
|
+
spree_promotions.id AS promotion_id,
|
51
|
+
spree_promotion_codes.id AS promotion_code_id,
|
52
|
+
friendly_order_promotions.created_at,
|
53
|
+
friendly_order_promotions.updated_at
|
54
|
+
FROM friendly_order_promotions
|
55
|
+
INNER JOIN friendly_promotions ON friendly_order_promotions.promotion_id = friendly_promotions.id
|
56
|
+
INNER JOIN spree_promotions ON spree_promotions.id = friendly_promotions.original_promotion_id
|
57
|
+
LEFT OUTER JOIN friendly_promotion_codes ON friendly_order_promotions.promotion_code_id = friendly_promotion_codes.id
|
58
|
+
LEFT OUTER JOIN spree_promotion_codes ON spree_promotion_codes.value = friendly_promotion_codes.value
|
59
|
+
WHERE NOT EXISTS (
|
60
|
+
SELECT NULL
|
61
|
+
FROM spree_orders_promotions
|
62
|
+
WHERE spree_orders_promotions.order_id = order_id
|
63
|
+
AND (spree_orders_promotions.promotion_code_id = promotion_code_id OR promotion_code_id IS NULL)
|
64
|
+
AND spree_orders_promotions.promotion_id = promotion_id
|
65
|
+
);
|
66
|
+
SQL
|
67
|
+
ActiveRecord::Base.connection.execute(sql)
|
68
|
+
|
69
|
+
SolidusFriendlyPromotions::OrderPromotion.delete_all
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spree/core/class_constantizer"
|
4
|
+
|
5
|
+
module SolidusFriendlyPromotions
|
6
|
+
class NestedClassSet
|
7
|
+
attr_reader :klass_sets
|
8
|
+
|
9
|
+
def initialize(hash = {})
|
10
|
+
@klass_sets = hash.map do |key, value|
|
11
|
+
[
|
12
|
+
key,
|
13
|
+
Spree::Core::ClassConstantizer::Set.new.tap do |set|
|
14
|
+
value.each { |klass_name| set << klass_name }
|
15
|
+
end
|
16
|
+
]
|
17
|
+
end.to_h
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](klass)
|
21
|
+
klass_sets[klass.name]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
PROMOTION_MAP = {
|
5
|
+
rules: {
|
6
|
+
Spree::Promotion::Rules::ItemTotal =>
|
7
|
+
SolidusFriendlyPromotions::Rules::ItemTotal,
|
8
|
+
Spree::Promotion::Rules::Product =>
|
9
|
+
SolidusFriendlyPromotions::Rules::Product,
|
10
|
+
Spree::Promotion::Rules::User =>
|
11
|
+
SolidusFriendlyPromotions::Rules::User,
|
12
|
+
Spree::Promotion::Rules::FirstOrder =>
|
13
|
+
SolidusFriendlyPromotions::Rules::FirstOrder,
|
14
|
+
Spree::Promotion::Rules::UserLoggedIn =>
|
15
|
+
SolidusFriendlyPromotions::Rules::UserLoggedIn,
|
16
|
+
Spree::Promotion::Rules::OneUsePerUser =>
|
17
|
+
SolidusFriendlyPromotions::Rules::OneUsePerUser,
|
18
|
+
Spree::Promotion::Rules::Taxon =>
|
19
|
+
SolidusFriendlyPromotions::Rules::Taxon,
|
20
|
+
Spree::Promotion::Rules::NthOrder =>
|
21
|
+
SolidusFriendlyPromotions::Rules::NthOrder,
|
22
|
+
Spree::Promotion::Rules::OptionValue =>
|
23
|
+
SolidusFriendlyPromotions::Rules::OptionValue,
|
24
|
+
Spree::Promotion::Rules::FirstRepeatPurchaseSince =>
|
25
|
+
SolidusFriendlyPromotions::Rules::FirstRepeatPurchaseSince,
|
26
|
+
Spree::Promotion::Rules::UserRole =>
|
27
|
+
SolidusFriendlyPromotions::Rules::UserRole,
|
28
|
+
Spree::Promotion::Rules::Store =>
|
29
|
+
SolidusFriendlyPromotions::Rules::Store
|
30
|
+
},
|
31
|
+
actions: {
|
32
|
+
Spree::Promotion::Actions::CreateAdjustment => ->(old_action) {
|
33
|
+
calculator = case old_action.calculator
|
34
|
+
when Spree::Calculator::FlatRate
|
35
|
+
SolidusFriendlyPromotions::Calculators::DistributedAmount.new(preferences: old_action.calculator.preferences)
|
36
|
+
when Spree::Calculator::FlatPercentItemTotal
|
37
|
+
SolidusFriendlyPromotions::Calculators::Percent.new(preferred_percent: old_action.calculator.preferred_flat_percent)
|
38
|
+
end
|
39
|
+
|
40
|
+
SolidusFriendlyPromotions::Actions::AdjustLineItem.new(
|
41
|
+
calculator: calculator
|
42
|
+
)
|
43
|
+
},
|
44
|
+
Spree::Promotion::Actions::CreateItemAdjustments => ->(old_action) {
|
45
|
+
preferences = old_action.calculator.preferences
|
46
|
+
calculator = case old_action.calculator
|
47
|
+
when Spree::Calculator::FlatRate
|
48
|
+
SolidusFriendlyPromotions::Calculators::FlatRate.new(preferences: preferences)
|
49
|
+
when Spree::Calculator::PercentOnLineItem
|
50
|
+
SolidusFriendlyPromotions::Calculators::Percent.new(preferences: preferences)
|
51
|
+
when Spree::Calculator::FlexiRate
|
52
|
+
SolidusFriendlyPromotions::Calculators::FlexiRate.new(preferences: preferences)
|
53
|
+
when Spree::Calculator::DistributedAmount
|
54
|
+
SolidusFriendlyPromotions::Calculators::DistributedAmount.new(preferences: preferences)
|
55
|
+
when Spree::Calculator::TieredFlatRate
|
56
|
+
SolidusFriendlyPromotions::Calculators::TieredFlatRate.new(preferences: preferences)
|
57
|
+
when Spree::Calculator::TieredPercent
|
58
|
+
SolidusFriendlyPromotions::Calculators::TieredPercent.new(preferences: preferences)
|
59
|
+
end
|
60
|
+
|
61
|
+
SolidusFriendlyPromotions::Actions::AdjustLineItem.new(
|
62
|
+
calculator: calculator
|
63
|
+
)
|
64
|
+
},
|
65
|
+
Spree::Promotion::Actions::CreateQuantityAdjustments => ->(old_action) {
|
66
|
+
preferences = old_action.calculator.preferences
|
67
|
+
calculator = case old_action.calculator
|
68
|
+
when Spree::Calculator::FlatRate
|
69
|
+
SolidusFriendlyPromotions::Calculators::FlatRate.new(preferences: preferences)
|
70
|
+
when Spree::Calculator::PercentOnLineItem
|
71
|
+
SolidusFriendlyPromotions::Calculators::Percent.new(preferences: preferences)
|
72
|
+
when Spree::Calculator::FlexiRate
|
73
|
+
SolidusFriendlyPromotions::Calculators::FlexiRate.new(preferences: preferences)
|
74
|
+
when Spree::Calculator::DistributedAmount
|
75
|
+
SolidusFriendlyPromotions::Calculators::DistributedAmount.new(preferences: preferences)
|
76
|
+
when Spree::Calculator::TieredFlatRate
|
77
|
+
SolidusFriendlyPromotions::Calculators::TieredFlatRate.new(preferences: preferences)
|
78
|
+
when Spree::Calculator::TieredPercent
|
79
|
+
SolidusFriendlyPromotions::Calculators::TieredPercent.new(preferences: preferences)
|
80
|
+
end
|
81
|
+
|
82
|
+
SolidusFriendlyPromotions::Actions::AdjustLineItemQuantityGroups.new(
|
83
|
+
preferred_group_size: old_action.preferred_group_size,
|
84
|
+
calculator: calculator
|
85
|
+
)
|
86
|
+
},
|
87
|
+
Spree::Promotion::Actions::FreeShipping => ->(old_action) {
|
88
|
+
SolidusFriendlyPromotions::Actions::AdjustShipment.new(
|
89
|
+
calculator: SolidusFriendlyPromotions::Calculators::Percent.new(
|
90
|
+
preferred_percent: 100
|
91
|
+
)
|
92
|
+
)
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusFriendlyPromotions
|
4
|
+
class PromotionMigrator
|
5
|
+
PROMOTION_IGNORED_ATTRIBUTES = ["id", "type", "promotion_category_id"]
|
6
|
+
|
7
|
+
attr_reader :promotion_map
|
8
|
+
|
9
|
+
def initialize(promotion_map)
|
10
|
+
@promotion_map = promotion_map
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
SolidusFriendlyPromotions::PromotionCategory.destroy_all
|
15
|
+
Spree::PromotionCategory.all.each do |promotion_category|
|
16
|
+
SolidusFriendlyPromotions::PromotionCategory.create!(promotion_category.attributes.except("id"))
|
17
|
+
end
|
18
|
+
|
19
|
+
SolidusFriendlyPromotions::Promotion.destroy_all
|
20
|
+
Spree::Promotion.all.each do |promotion|
|
21
|
+
new_promotion = copy_promotion(promotion)
|
22
|
+
if promotion.promotion_category&.name.present?
|
23
|
+
new_promotion.category = SolidusFriendlyPromotions::PromotionCategory.find_by(
|
24
|
+
name: promotion.promotion_category.name
|
25
|
+
)
|
26
|
+
end
|
27
|
+
new_promotion.rules = promotion.rules.flat_map do |old_promotion_rule|
|
28
|
+
generate_new_promotion_rules(old_promotion_rule)
|
29
|
+
end
|
30
|
+
new_promotion.actions = promotion.actions.flat_map do |old_promotion_action|
|
31
|
+
generate_new_promotion_actions(old_promotion_action)&.tap do |new_promotion_action|
|
32
|
+
new_promotion_action.original_promotion_action = old_promotion_action
|
33
|
+
end
|
34
|
+
end.compact
|
35
|
+
new_promotion.save!
|
36
|
+
copy_promotion_code_batches(new_promotion)
|
37
|
+
copy_promotion_codes(new_promotion)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def copy_promotion_code_batches(new_promotion)
|
44
|
+
sql = <<~SQL
|
45
|
+
INSERT INTO friendly_promotion_code_batches (promotion_id, base_code, number_of_codes, email, error, state, created_at, updated_at, join_characters)
|
46
|
+
SELECT friendly_promotions.id AS promotion_id, base_code, number_of_codes, email, error, state, spree_promotion_code_batches.created_at, spree_promotion_code_batches.updated_at, join_characters
|
47
|
+
FROM spree_promotion_code_batches
|
48
|
+
INNER JOIN spree_promotions ON spree_promotion_code_batches.promotion_id = spree_promotions.id
|
49
|
+
INNER JOIN friendly_promotions ON spree_promotions.id = friendly_promotions.original_promotion_id
|
50
|
+
WHERE spree_promotion_code_batches.promotion_id = #{new_promotion.original_promotion_id};
|
51
|
+
SQL
|
52
|
+
SolidusFriendlyPromotions::PromotionCodeBatch.connection.execute(sql)
|
53
|
+
end
|
54
|
+
|
55
|
+
def copy_promotion_codes(new_promotion)
|
56
|
+
sql = <<~SQL
|
57
|
+
INSERT INTO friendly_promotion_codes (promotion_id, promotion_code_batch_id, value, created_at, updated_at)
|
58
|
+
SELECT friendly_promotions.id AS promotion_id, friendly_promotion_code_batches.id AS promotion_code_batch_id, value, spree_promotion_codes.created_at, spree_promotion_codes.updated_at
|
59
|
+
FROM spree_promotion_codes
|
60
|
+
LEFT OUTER JOIN spree_promotion_code_batches ON spree_promotion_code_batches.id = spree_promotion_codes.promotion_code_batch_id
|
61
|
+
LEFT OUTER JOIN friendly_promotion_code_batches ON friendly_promotion_code_batches.base_code = spree_promotion_code_batches.base_code
|
62
|
+
INNER JOIN spree_promotions ON spree_promotion_codes.promotion_id = spree_promotions.id
|
63
|
+
INNER JOIN friendly_promotions ON spree_promotions.id = friendly_promotions.original_promotion_id
|
64
|
+
WHERE spree_promotion_codes.promotion_id = #{new_promotion.original_promotion_id};
|
65
|
+
SQL
|
66
|
+
SolidusFriendlyPromotions::PromotionCode.connection.execute(sql)
|
67
|
+
end
|
68
|
+
|
69
|
+
def copy_promotion(old_promotion)
|
70
|
+
SolidusFriendlyPromotions::Promotion.new(
|
71
|
+
old_promotion.attributes.except(*PROMOTION_IGNORED_ATTRIBUTES).merge(
|
72
|
+
customer_label: old_promotion.name,
|
73
|
+
original_promotion: old_promotion
|
74
|
+
)
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_new_promotion_actions(old_promotion_action)
|
79
|
+
promo_action_config = promotion_map[:actions][old_promotion_action.class]
|
80
|
+
if promo_action_config.nil?
|
81
|
+
puts("#{old_promotion_action.class} is not supported")
|
82
|
+
return nil
|
83
|
+
end
|
84
|
+
promo_action_config.call(old_promotion_action)
|
85
|
+
end
|
86
|
+
|
87
|
+
def generate_new_promotion_rules(old_promotion_rule)
|
88
|
+
new_promo_rule_class = promotion_map[:rules][old_promotion_rule.class]
|
89
|
+
if new_promo_rule_class.nil?
|
90
|
+
puts("#{old_promotion_rule.class} is not supported")
|
91
|
+
[]
|
92
|
+
elsif new_promo_rule_class.respond_to?(:call)
|
93
|
+
new_promo_rule_class.call(old_promotion_rule)
|
94
|
+
else
|
95
|
+
new_rule = new_promo_rule_class.new(old_promotion_rule.attributes.except(*PROMOTION_IGNORED_ATTRIBUTES))
|
96
|
+
new_rule.preload_relations.each do |relation|
|
97
|
+
new_rule.send("#{relation}=", old_promotion_rule.send(relation))
|
98
|
+
end
|
99
|
+
[new_rule]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|