solidus_friendly_promotions 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +61 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +1 -0
  5. data/.github_changelog_generator +2 -0
  6. data/.gitignore +21 -0
  7. data/.rspec +2 -0
  8. data/.rubocop.yml +29 -0
  9. data/.rubocop_todo.yml +157 -0
  10. data/.standard.yml +4 -0
  11. data/CHANGELOG.md +1 -0
  12. data/Gemfile +42 -0
  13. data/LICENSE +26 -0
  14. data/MIGRATING.md +134 -0
  15. data/README.md +144 -0
  16. data/Rakefile +7 -0
  17. data/app/assets/config/solidus_friendly_promotions/manifest.js +7 -0
  18. data/app/controllers/solidus_friendly_promotions/admin/base_controller.rb +54 -0
  19. data/app/controllers/solidus_friendly_promotions/admin/promotion_actions_controller.rb +103 -0
  20. data/app/controllers/solidus_friendly_promotions/admin/promotion_categories_controller.rb +13 -0
  21. data/app/controllers/solidus_friendly_promotions/admin/promotion_code_batches_controller.rb +30 -0
  22. data/app/controllers/solidus_friendly_promotions/admin/promotion_codes_controller.rb +58 -0
  23. data/app/controllers/solidus_friendly_promotions/admin/promotion_rules_controller.rb +105 -0
  24. data/app/controllers/solidus_friendly_promotions/admin/promotions_controller.rb +64 -0
  25. data/app/decorators/models/solidus_friendly_promotions/adjustment_decorator.rb +26 -0
  26. data/app/decorators/models/solidus_friendly_promotions/line_item_decorator.rb +7 -0
  27. data/app/decorators/models/solidus_friendly_promotions/order_decorator.rb +42 -0
  28. data/app/decorators/models/solidus_friendly_promotions/order_recalculator_decorator.rb +13 -0
  29. data/app/decorators/models/solidus_friendly_promotions/shipment_decorator.rb +14 -0
  30. data/app/decorators/models/solidus_friendly_promotions/shipping_rate_decorator.rb +29 -0
  31. data/app/helpers/solidus_friendly_promotions/admin/promotion_actions_helper.rb +23 -0
  32. data/app/helpers/solidus_friendly_promotions/admin/promotion_rules_helper.rb +25 -0
  33. data/app/javascript/solidus_friendly_promotions/controllers/application.js +9 -0
  34. data/app/javascript/solidus_friendly_promotions/controllers/calculator_tiers_controller.js +37 -0
  35. data/app/javascript/solidus_friendly_promotions/controllers/flash_controller.js +10 -0
  36. data/app/javascript/solidus_friendly_promotions/controllers/index.js +8 -0
  37. data/app/javascript/solidus_friendly_promotions/controllers/product_option_values_controller.js +62 -0
  38. data/app/javascript/solidus_friendly_promotions/jquery/option_value_picker.js +44 -0
  39. data/app/javascript/solidus_friendly_promotions.js +12 -0
  40. data/app/jobs/solidus_friendly_promotions/promotion_code_batch_job.rb +26 -0
  41. data/app/mailers/solidus_friendly_promotions/promotion_code_batch_mailer.rb +15 -0
  42. data/app/models/concerns/solidus_friendly_promotions/discountable_amount.rb +21 -0
  43. data/app/models/concerns/solidus_friendly_promotions/rules/line_item_applicable_order_rule.rb +23 -0
  44. data/app/models/concerns/solidus_friendly_promotions/rules/line_item_level_rule.rb +15 -0
  45. data/app/models/concerns/solidus_friendly_promotions/rules/order_level_rule.rb +15 -0
  46. data/app/models/concerns/solidus_friendly_promotions/rules/shipment_level_rule.rb +15 -0
  47. data/app/models/solidus_friendly_promotions/actions/adjust_line_item.rb +15 -0
  48. data/app/models/solidus_friendly_promotions/actions/adjust_line_item_quantity_groups.rb +116 -0
  49. data/app/models/solidus_friendly_promotions/actions/adjust_shipment.rb +15 -0
  50. data/app/models/solidus_friendly_promotions/calculators/distributed_amount.rb +37 -0
  51. data/app/models/solidus_friendly_promotions/calculators/flat_rate.rb +21 -0
  52. data/app/models/solidus_friendly_promotions/calculators/flexi_rate.rb +24 -0
  53. data/app/models/solidus_friendly_promotions/calculators/percent.rb +17 -0
  54. data/app/models/solidus_friendly_promotions/calculators/tiered_flat_rate.rb +56 -0
  55. data/app/models/solidus_friendly_promotions/calculators/tiered_percent.rb +66 -0
  56. data/app/models/solidus_friendly_promotions/distributed_amounts_handler.rb +43 -0
  57. data/app/models/solidus_friendly_promotions/eligibility_result.rb +5 -0
  58. data/app/models/solidus_friendly_promotions/eligibility_results.rb +48 -0
  59. data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/choose_discounts.rb +21 -0
  60. data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/discount_order.rb +76 -0
  61. data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/load_promotions.rb +54 -0
  62. data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster/persist_discounted_order.rb +81 -0
  63. data/app/models/solidus_friendly_promotions/friendly_promotion_adjuster.rb +25 -0
  64. data/app/models/solidus_friendly_promotions/item_discount.rb +21 -0
  65. data/app/models/solidus_friendly_promotions/migration_support/order_promotion_syncer.rb +54 -0
  66. data/app/models/solidus_friendly_promotions/order_promotion.rb +23 -0
  67. data/app/models/solidus_friendly_promotions/permission_sets/friendly_promotion_management.rb +15 -0
  68. data/app/models/solidus_friendly_promotions/products_promotion_rule.rb +8 -0
  69. data/app/models/solidus_friendly_promotions/promotion.rb +166 -0
  70. data/app/models/solidus_friendly_promotions/promotion_action.rb +73 -0
  71. data/app/models/solidus_friendly_promotions/promotion_category.rb +9 -0
  72. data/app/models/solidus_friendly_promotions/promotion_code/batch_builder.rb +72 -0
  73. data/app/models/solidus_friendly_promotions/promotion_code.rb +55 -0
  74. data/app/models/solidus_friendly_promotions/promotion_code_batch.rb +25 -0
  75. data/app/models/solidus_friendly_promotions/promotion_handler/coupon.rb +113 -0
  76. data/app/models/solidus_friendly_promotions/promotion_handler/page.rb +30 -0
  77. data/app/models/solidus_friendly_promotions/promotion_rule.rb +55 -0
  78. data/app/models/solidus_friendly_promotions/promotion_rules_store.rb +8 -0
  79. data/app/models/solidus_friendly_promotions/promotion_rules_taxon.rb +8 -0
  80. data/app/models/solidus_friendly_promotions/promotion_rules_user.rb +8 -0
  81. data/app/models/solidus_friendly_promotions/rules/discounted_item_total.rb +22 -0
  82. data/app/models/solidus_friendly_promotions/rules/first_order.rb +31 -0
  83. data/app/models/solidus_friendly_promotions/rules/first_repeat_purchase_since.rb +31 -0
  84. data/app/models/solidus_friendly_promotions/rules/item_total.rb +86 -0
  85. data/app/models/solidus_friendly_promotions/rules/line_item_option_value.rb +37 -0
  86. data/app/models/solidus_friendly_promotions/rules/line_item_product.rb +52 -0
  87. data/app/models/solidus_friendly_promotions/rules/line_item_taxon.rb +55 -0
  88. data/app/models/solidus_friendly_promotions/rules/minimum_quantity.rb +48 -0
  89. data/app/models/solidus_friendly_promotions/rules/nth_order.rb +40 -0
  90. data/app/models/solidus_friendly_promotions/rules/one_use_per_user.rb +25 -0
  91. data/app/models/solidus_friendly_promotions/rules/option_value.rb +28 -0
  92. data/app/models/solidus_friendly_promotions/rules/product.rb +85 -0
  93. data/app/models/solidus_friendly_promotions/rules/shipping_method.rb +19 -0
  94. data/app/models/solidus_friendly_promotions/rules/store.rb +26 -0
  95. data/app/models/solidus_friendly_promotions/rules/taxon.rb +98 -0
  96. data/app/models/solidus_friendly_promotions/rules/user.rb +35 -0
  97. data/app/models/solidus_friendly_promotions/rules/user_logged_in.rb +16 -0
  98. data/app/models/solidus_friendly_promotions/rules/user_role.rb +42 -0
  99. data/app/models/solidus_friendly_promotions/shipping_rate_discount.rb +11 -0
  100. data/app/models/solidus_friendly_promotions/simple_order_contents.rb +27 -0
  101. data/app/models/solidus_friendly_promotions.rb +7 -0
  102. data/app/views/solidus_friendly_promotions/admin/promotion_actions/_calculator_select.html.erb +16 -0
  103. data/app/views/solidus_friendly_promotions/admin/promotion_actions/_form.html.erb +3 -0
  104. data/app/views/solidus_friendly_promotions/admin/promotion_actions/_promotion_action.html.erb +29 -0
  105. data/app/views/solidus_friendly_promotions/admin/promotion_actions/_type_select.html.erb +14 -0
  106. data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_line_item.html.erb +6 -0
  107. data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_line_item_quantity_groups.html.erb +13 -0
  108. data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_adjust_shipment.html.erb +6 -0
  109. data/app/views/solidus_friendly_promotions/admin/promotion_actions/actions/_calculator_fields.erb +8 -0
  110. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/_default_fields.html.erb +6 -0
  111. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/distributed_amount/_fields.html.erb +56 -0
  112. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/flat_rate/_fields.html.erb +6 -0
  113. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_flat_rate/_fields.html.erb +34 -0
  114. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_flat_rate/_tier_fields.html.erb +32 -0
  115. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_percent/_fields.html.erb +34 -0
  116. data/app/views/solidus_friendly_promotions/admin/promotion_actions/calculators/tiered_percent/_tier_fields.html.erb +32 -0
  117. data/app/views/solidus_friendly_promotions/admin/promotion_actions/edit.html.erb +23 -0
  118. data/app/views/solidus_friendly_promotions/admin/promotion_actions/new.html.erb +26 -0
  119. data/app/views/solidus_friendly_promotions/admin/promotion_categories/_form.html.erb +14 -0
  120. data/app/views/solidus_friendly_promotions/admin/promotion_categories/edit.html.erb +10 -0
  121. data/app/views/solidus_friendly_promotions/admin/promotion_categories/index.html.erb +47 -0
  122. data/app/views/solidus_friendly_promotions/admin/promotion_categories/new.html.erb +10 -0
  123. data/app/views/solidus_friendly_promotions/admin/promotion_codes/index.csv.ruby +8 -0
  124. data/app/views/solidus_friendly_promotions/admin/promotion_codes/index.html.erb +32 -0
  125. data/app/views/solidus_friendly_promotions/admin/promotion_codes/new.html.erb +31 -0
  126. data/app/views/solidus_friendly_promotions/admin/promotion_rules/_promotion_rule.html.erb +22 -0
  127. data/app/views/solidus_friendly_promotions/admin/promotion_rules/_type_select.html.erb +20 -0
  128. data/app/views/solidus_friendly_promotions/admin/promotion_rules/new.html.erb +24 -0
  129. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_first_order.html.erb +3 -0
  130. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_first_repeat_purchase_since.html.erb +6 -0
  131. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_item_total.html.erb +17 -0
  132. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_option_value.html.erb +25 -0
  133. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_product.html.erb +21 -0
  134. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_line_item_taxon.html.erb +17 -0
  135. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_minimum_quantity.html.erb +5 -0
  136. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_nth_order.html.erb +15 -0
  137. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_one_use_per_user.html.erb +3 -0
  138. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_option_value.html.erb +63 -0
  139. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_product.html.erb +44 -0
  140. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_shipping_method.html.erb +10 -0
  141. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_store.html.erb +9 -0
  142. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_taxon.html.erb +44 -0
  143. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user.html.erb +7 -0
  144. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user_logged_in.html.erb +3 -0
  145. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/_user_role.html.erb +15 -0
  146. data/app/views/solidus_friendly_promotions/admin/promotion_rules/rules/line_item_option_value/_option_value_fields.html.erb +17 -0
  147. data/app/views/solidus_friendly_promotions/admin/promotions/_activations_edit.html.erb +22 -0
  148. data/app/views/solidus_friendly_promotions/admin/promotions/_activations_new.html.erb +43 -0
  149. data/app/views/solidus_friendly_promotions/admin/promotions/_form.html.erb +96 -0
  150. data/app/views/solidus_friendly_promotions/admin/promotions/edit.html.erb +73 -0
  151. data/app/views/solidus_friendly_promotions/admin/promotions/index.html.erb +124 -0
  152. data/app/views/solidus_friendly_promotions/admin/promotions/new.html.erb +9 -0
  153. data/app/views/solidus_friendly_promotions/admin/shared/_promotion_sub_menu.html.erb +14 -0
  154. data/app/views/solidus_friendly_promotions/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
  155. data/app/views/solidus_friendly_promotions/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
  156. data/bin/console +17 -0
  157. data/bin/importmap +4 -0
  158. data/bin/rails +7 -0
  159. data/bin/rails-engine +13 -0
  160. data/bin/rails-sandbox +16 -0
  161. data/bin/rake +7 -0
  162. data/bin/sandbox +75 -0
  163. data/bin/setup +8 -0
  164. data/config/importmap.rb +12 -0
  165. data/config/initializers/solidus_friendly_promotions.rb +3 -0
  166. data/config/locales/en.yml +255 -0
  167. data/config/routes.rb +18 -0
  168. data/db/migrate/20230703101637_create_promotions.rb +16 -0
  169. data/db/migrate/20230703141116_create_promotion_categories.rb +14 -0
  170. data/db/migrate/20230703143943_create_promotion_rules.rb +12 -0
  171. data/db/migrate/20230704083830_add_rule_tables.rb +31 -0
  172. data/db/migrate/20230704093625_create_promotion_actions.rb +14 -0
  173. data/db/migrate/20230704102444_create_promotion_codes.rb +11 -0
  174. data/db/migrate/20230704102656_create_promotion_code_batches.rb +33 -0
  175. data/db/migrate/20230705171556_create_friendly_order_promotions.rb +11 -0
  176. data/db/migrate/20230725074235_create_shipping_rate_discounts.rb +12 -0
  177. data/db/migrate/20230928093138_add_lane_to_solidus_friendly_promotions_promotions.rb +5 -0
  178. data/db/migrate/20231006134042_add_customer_label_to_promotions.rb +7 -0
  179. data/db/migrate/20231011100059_add_db_comments_to_friendly_order_promotions.rb +61 -0
  180. data/db/migrate/20231011120928_add_db_comments_to_friendly_promotion_rules_taxons.rb +54 -0
  181. data/db/migrate/20231011131324_add_db_comments_to_friendly_promotion_rules.rb +60 -0
  182. data/db/migrate/20231011142040_add_db_comments_to_friendly_promotion_rules_users.rb +53 -0
  183. data/db/migrate/20231011154553_allow_null_promotion_ids.rb +9 -0
  184. data/db/migrate/20231011155822_add_db_comments_to_friendly_promotions.rb +123 -0
  185. data/db/migrate/20231011163030_add_db_comments_to_friendly_promotion_codes.rb +60 -0
  186. data/db/migrate/20231011173312_add_db_comments_to_friendly_promotion_code_batches.rb +91 -0
  187. data/db/migrate/20231011184205_add_db_comments_to_friendly_promotion_rules_stores.rb +53 -0
  188. data/db/migrate/20231011190222_add_db_comments_to_friendly_promotion_actions.rb +68 -0
  189. data/db/migrate/20231012020928_add_db_comments_to_friendly_products_promotion_rules.rb +52 -0
  190. data/db/migrate/20231012120928_add_db_comments_to_friendly_promotion_categories.rb +52 -0
  191. data/db/migrate/20231013181921_add_original_promotion_ids.rb +6 -0
  192. data/lib/generators/solidus_friendly_promotions/install/install_generator.rb +38 -0
  193. data/lib/generators/solidus_friendly_promotions/install/templates/initializer.rb +118 -0
  194. data/lib/solidus_friendly_promotions/configuration.rb +52 -0
  195. data/lib/solidus_friendly_promotions/engine.rb +37 -0
  196. data/lib/solidus_friendly_promotions/migrate_adjustments.rb +62 -0
  197. data/lib/solidus_friendly_promotions/migrate_order_promotions.rb +73 -0
  198. data/lib/solidus_friendly_promotions/nested_class_set.rb +24 -0
  199. data/lib/solidus_friendly_promotions/promotion_map.rb +96 -0
  200. data/lib/solidus_friendly_promotions/promotion_migrator.rb +103 -0
  201. data/lib/solidus_friendly_promotions/testing_support/factories/friendly_order_factory.rb +20 -0
  202. data/lib/solidus_friendly_promotions/testing_support/factories/friendly_order_promotion_factory.rb +8 -0
  203. data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_category_factory.rb +7 -0
  204. data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_code_factory.rb +8 -0
  205. data/lib/solidus_friendly_promotions/testing_support/factories/friendly_promotion_factory.rb +91 -0
  206. data/lib/solidus_friendly_promotions/testing_support/factories/friendly_shipping_rate_discount_factory.rb +14 -0
  207. data/lib/solidus_friendly_promotions/testing_support.rb +9 -0
  208. data/lib/solidus_friendly_promotions/version.rb +5 -0
  209. data/lib/solidus_friendly_promotions.rb +18 -0
  210. data/lib/tasks/solidus_friendly_promotions/migrate_adjustments.rake +17 -0
  211. data/lib/tasks/solidus_friendly_promotions/migrate_existing_promotions.rake +12 -0
  212. data/lib/tasks/solidus_friendly_promotions/migrate_order_promotions.rake +17 -0
  213. data/solidus_friendly_promotions.gemspec +40 -0
  214. metadata +392 -0
@@ -0,0 +1,14 @@
1
+ <ul class="admin-subnav" data-hook="admin_promotion_sub_tabs">
2
+ <% if can? :admin, SolidusFriendlyPromotions::Promotion %>
3
+ <%= tab url: solidus_friendly_promotions.admin_promotions_path, label: :promotions %>
4
+ <% end %>
5
+ <% if can? :admin, SolidusFriendlyPromotions::PromotionCategory %>
6
+ <%= tab url: solidus_friendly_promotions.admin_promotion_categories_path, label: :promotion_categories %>
7
+ <% end %>
8
+ <% if can? :admin, Spree::Promotion && Spree::Promotion.any? %>
9
+ <%= tab url: spree.admin_promotions_path, label: :legacy_promotions %>
10
+ <% end %>
11
+ <% if can? :admin, Spree::PromotionCategory && Spree::PromotionCategory.any? %>
12
+ <%= tab url: spree.admin_promotion_categories_path, label: :legacy_promotion_categories %>
13
+ <% end %>
14
+ </ul>
@@ -0,0 +1,2 @@
1
+ <%= t(".message", error: @promotion_code_batch.error) %>
2
+ <%= @promotion_code_batch.promotion.name %>
@@ -0,0 +1,2 @@
1
+ <%= t(".message", number_of_codes: 10) %>
2
+ <%= @promotion_code_batch.promotion.name %>
data/bin/console ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require "bundler/setup"
6
+ require "solidus_friendly_promotions"
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+ $LOAD_PATH.unshift(*Dir["#{__dir__}/../app/*"])
11
+
12
+ # (If you use this, don't forget to add pry to your Gemfile!)
13
+ # require "pry"
14
+ # Pry.start
15
+
16
+ require "irb"
17
+ IRB.start(__FILE__)
data/bin/importmap ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../spec/dummy/config/application"
4
+ require "importmap/commands"
data/bin/rails ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if %w[g generate].include? ARGV.first
4
+ exec "#{__dir__}/rails-engine", *ARGV
5
+ else
6
+ exec "#{__dir__}/rails-sandbox", *ARGV
7
+ end
data/bin/rails-engine ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('..', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/solidus_friendly_promotions/engine', __dir__)
7
+
8
+ # Set up gems listed in the Gemfile.
9
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
10
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
11
+
12
+ require 'rails/all'
13
+ require 'rails/engine/commands'
data/bin/rails-sandbox ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ app_root = 'sandbox'
4
+
5
+ unless File.exist? "#{app_root}/bin/rails"
6
+ warn 'Creating the sandbox app...'
7
+ Dir.chdir "#{__dir__}/.." do
8
+ system "#{__dir__}/sandbox" or begin
9
+ warn 'Automatic creation of the sandbox app failed'
10
+ exit 1
11
+ end
12
+ end
13
+ end
14
+
15
+ Dir.chdir app_root
16
+ exec 'bin/rails', *ARGV
data/bin/rake ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "rubygems"
5
+ require "bundler/setup"
6
+
7
+ load Gem.bin_path("rake", "rake")
data/bin/sandbox ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+ test -z "${DEBUG+empty_string}" || set -x
5
+
6
+ test "$DB" = "sqlite" && export DB="sqlite3"
7
+
8
+ if [ -z "$PAYMENT_METHOD" ]
9
+ then
10
+ PAYMENT_METHOD="none"
11
+ fi
12
+
13
+ if [ -z "$SOLIDUS_BRANCH" ]
14
+ then
15
+ echo "~~> Use 'export SOLIDUS_BRANCH=[main|v4.0|...]' to control the Solidus branch"
16
+ SOLIDUS_BRANCH="main"
17
+ fi
18
+ echo "~~> Using branch $SOLIDUS_BRANCH of solidus"
19
+
20
+ extension_name="solidus_friendly_promotions"
21
+
22
+ # Stay away from the bundler env of the containing extension.
23
+ function unbundled {
24
+ ruby -rbundler -e'
25
+ Bundler.with_unbundled_env {system *ARGV}' -- \
26
+ env BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES=true $@
27
+ }
28
+
29
+ echo "~~~> Removing the old sandbox"
30
+ rm -rf ./sandbox
31
+
32
+ echo "~~~> Creating a pristine Rails app"
33
+ rails new sandbox \
34
+ --database="${DB:-sqlite3}" \
35
+ --skip-git \
36
+ --skip-keeps \
37
+ --skip-rc \
38
+ --skip-bootsnap \
39
+ --skip-test
40
+
41
+ if [ ! -d "sandbox" ]; then
42
+ echo 'sandbox rails application failed'
43
+ exit 1
44
+ fi
45
+
46
+ echo "~~~> Adding solidus (with i18n and authentication) and your gem to the Gemfile"
47
+ cd ./sandbox
48
+ cat <<RUBY >> Gemfile
49
+ gem 'solidus', github: 'solidusio/solidus', branch: '$SOLIDUS_BRANCH'
50
+ gem 'rails-i18n'
51
+ gem 'solidus_i18n'
52
+
53
+ gem '$extension_name', path: '..'
54
+
55
+ group :test, :development do
56
+ platforms :mri do
57
+ gem 'pry-byebug'
58
+ end
59
+ end
60
+ RUBY
61
+
62
+ unbundled bundle install --gemfile Gemfile
63
+
64
+ unbundled bundle exec rake db:drop db:create
65
+
66
+ unbundled bin/rails generate solidus:install \
67
+ --auto-accept \
68
+ $@
69
+
70
+ unbundled bundle exec rails generate solidus:auth:install --auto-run-migrations
71
+ unbundled bundle exec rails generate ${extension_name}:install --auto-run-migrations
72
+
73
+ echo
74
+ echo "🚀 Sandbox app successfully created for $extension_name!"
75
+ echo "🧪 This app is intended for test purposes."
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ gem install bundler --conservative
7
+ bundle update
8
+ bin/rake clobber
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
4
+
5
+ pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
6
+ pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
7
+ pin_all_from SolidusFriendlyPromotions::Engine.root.join("app/javascript/solidus_friendly_promotions/controllers"),
8
+ under: "solidus_friendly_promotions/controllers"
9
+ pin_all_from SolidusFriendlyPromotions::Engine.root.join("app/javascript/solidus_friendly_promotions/jquery"),
10
+ under: "solidus_friendly_promotions/jquery"
11
+
12
+ pin "solidus_friendly_promotions", to: "solidus_friendly_promotions.js", preload: true
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative SolidusFriendlyPromotions::Engine.root.join("app/models/solidus_friendly_promotions.rb")
@@ -0,0 +1,255 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree:
6
+ admin:
7
+ tab:
8
+ promotions: Promotions
9
+ promotion_categories: Promotion Categories
10
+ legacy_promotions: Legacy Promotions
11
+ legacy_promotion_categories: Legacy Promotion Categories
12
+ solidus_friendly_promotions:
13
+ actions: Actions
14
+ adjustment_labels:
15
+ line_item: "%{promotion} (%{promotion_customer_label})"
16
+ shipment: "%{promotion} (%{promotion_customer_label})"
17
+ shipping_rate: "%{promotion} (%{promotion_customer_label})"
18
+ adjustment_type: Adjustment type
19
+ add_action: New Action
20
+ add_rule: New Rule
21
+ order_rules: Order Rules
22
+ line_item_rules: Line Item Rules
23
+ shipment_rules: Shipment Rules
24
+ line_item_actions: Line Item Actions
25
+ shipment_actions: Shipment Actions
26
+ invalid_promotion_rule_level: Invalid Promotion Rule Level. Must be one of "order", "shipment", or "line_item"
27
+ invalid_promotion_action: Invalid promotion action.
28
+ invalid_promotion_rule: Invalid promotion rule.
29
+ create_promotion_code: Create promotion code
30
+ current_promotion_usage: 'Current Usage: %{count}'
31
+ discount_rules: Promotion Rules
32
+ download_promotion_codes_list: Download codes list
33
+ new_promotion: New Promotion
34
+ new_promotion_category: New Promotion Category
35
+ new_promotion_code_batch: New Promotion Code Batch
36
+ number_of_codes: Number of codes
37
+ legacy_promotions: Legacy Promotions
38
+ no_rules_added: No Rules Added
39
+ promotion_successfully_created: Promotion has been successfully created!
40
+ promotion_total_changed_before_complete: One or more of the promotions on your order have become ineligible and were removed. Please check the new order amounts and try again.
41
+ view_promotion_codes_list: View codes list
42
+ promotion_rules:
43
+ line_item_product:
44
+ match_policies:
45
+ include: Line item's product is one of the chosen products
46
+ exclude: Line item's product is not one of the chosen products
47
+ line_item_taxon:
48
+ match_policies:
49
+ include: Line item's product has one of the chosen taxons
50
+ exclude: Line item's product does not have one of the chosen taxons
51
+ hints:
52
+ solidus_friendly_promotions/calculator:
53
+ promotions: This is used to determine the promotional discount to be applied to an order, an item, or shipping charges.
54
+ coupon_code: Coupon code
55
+ eligibility_results:
56
+ coupon_code_applied: The coupon code was successfully applied to your order.
57
+ coupon_code_removed: The coupon code was successfully removed from this order.
58
+ eligibility_errors:
59
+ coupon_code_already_applied: The coupon code has already been applied to this order
60
+ coupon_code_expired: The coupon code is expired
61
+ coupon_code_max_usage: Coupon code usage limit exceeded
62
+ coupon_code_not_eligible: This coupon code is not eligible for this order
63
+ coupon_code_not_found: The coupon code you entered doesn't exist. Please try again.
64
+ coupon_code_not_present: The coupon code you are trying to remove is not present on this order.
65
+ coupon_code_unknown_error: This coupon code could not be applied to the cart at this time.
66
+ solidus_friendly_promotions/rules/first_order:
67
+ not_first_order: This coupon code can only be applied to your first order.
68
+ solidus_friendly_promotions/rules/first_repeat_purchase_since:
69
+ solidus_friendly_promotions/rules/item_total:
70
+ item_total_doesnt_match_with_operator: This coupon code can't be applied to orders %{operator} %{amount}.
71
+ item_total_less_than: This coupon code can't be applied to orders less than %{amount}.
72
+ item_total_less_than_or_equal: This coupon code can't be applied to orders less than or equal to %{amount}.
73
+ solidus_friendly_promotions/rules/discounted_item_total:
74
+ item_total_doesnt_match_with_operator: This coupon code can't be applied to orders %{operator} %{amount}.
75
+ item_total_less_than: This coupon code can't be applied to orders less than %{amount}.
76
+ item_total_less_than_or_equal: This coupon code can't be applied to orders less than or equal to %{amount}.
77
+ solidus_friendly_promotions/rules/landing_page:
78
+ solidus_friendly_promotions/rules/nth_order:
79
+ solidus_friendly_promotions/rules/one_use_per_user:
80
+ no_user_specified: You need to login before applying this coupon code.
81
+ limit_once_per_user: This coupon code can only be used once per user.
82
+ solidus_friendly_promotions/rules/option_value:
83
+ solidus_friendly_promotions/rules/line_item_option_value:
84
+ solidus_friendly_promotions/rules/product:
85
+ has_excluded_product: Your cart contains a product that prevents this coupon code from being applied.
86
+ missing_product: This coupon code can't be applied because you don't have all of the necessary products in your cart.
87
+ no_applicable_products: You need to add an applicable product before applying this coupon code.
88
+ solidus_friendly_promotions/rules/line_item_product:
89
+ has_excluded_product: Your cart contains a product that prevents this coupon code from being applied.
90
+ missing_product: This coupon code can't be applied because you don't have all of the necessary products in your cart.
91
+ no_applicable_products: You need to add an applicable product before applying this coupon code.
92
+ solidus_friendly_promotions/rules/taxon:
93
+ has_excluded_taxon: Your cart contains a product from an excluded category that prevents this coupon code from being applied.
94
+ missing_taxon: You need to add a product from all applicable categories before applying this coupon code.
95
+ no_matching_taxons: You need to add a product from an applicable category before applying this coupon code.
96
+ solidus_friendly_promotions/rules/line_item_taxon:
97
+ has_excluded_taxon: Your cart contains a product from an excluded category that prevents this coupon code from being applied.
98
+ missing_taxon: You need to add a product from all applicable categories before applying this coupon code.
99
+ no_matching_taxons: You need to add a product from an applicable category before applying this coupon code.
100
+ solidus_friendly_promotions/rules/user:
101
+ no_user_specified: You need to login before applying this coupon code.
102
+ solidus_friendly_promotions/rules/user_logged_in:
103
+ no_user_specified: You need to login before applying this coupon code.
104
+ solidus_friendly_promotions/rules/user_role:
105
+ solidus_friendly_promotions/rules/minimum_quantity:
106
+ quantity_less_than_minimum:
107
+ one: "You need to add a least 1 applicable item to your order."
108
+ other: "You need to add a least %{count} applicable items to your order."
109
+ product_rule:
110
+ choose_products: Choose products
111
+ label: Order must contain %{select} these products
112
+ match_all: all of
113
+ match_any: at least one of
114
+ match_none: none of
115
+ match_only: only
116
+ product_source:
117
+ group: From product group
118
+ manual: Manually choose
119
+ taxon_rule:
120
+ choose_taxons: Choose taxons
121
+ label: Order must contain %{select} of these taxons
122
+ match_all: all
123
+ match_any: at least one
124
+ match_none: none
125
+ crud:
126
+ add: Add
127
+ destroy: Delete
128
+ update: Update
129
+ admin:
130
+ promotions:
131
+ actions:
132
+ calculator_label: Calculated by
133
+ activations_edit:
134
+ auto: All orders will attempt to use this promotion
135
+ multiple_codes_html: This promotion uses %{count} promotion codes
136
+ single_code_html: 'This promotion uses the promotion code: <code>%{code}</code>'
137
+ activations_new:
138
+ auto: Apply to all orders
139
+ multiple_codes: Multiple promotion codes
140
+ single_code: Single promotion code
141
+ form:
142
+ activation: Activation
143
+ expires_at_placeholder: Never
144
+ general: General
145
+ starts_at_placeholder: Immediately
146
+ edit:
147
+ order_rules: Order Rules
148
+ promotion_status:
149
+ active: Active
150
+ expired: Expired
151
+ inactive: Inactive
152
+ not_started: Not started
153
+ promotion_code_batch_mailer:
154
+ promotion_code_batch_errored:
155
+ message: 'Promotion code batch errored (%{error}) for promotion: '
156
+ subject: Promotion code batch errored
157
+ promotion_code_batch_finished:
158
+ message: 'All %{number_of_codes} codes have been created for promotion: '
159
+ subject: Promotion code batch finished
160
+ activerecord:
161
+ models:
162
+ solidus_friendly_promotions/actions/adjust_shipment: Discount matching shipments
163
+ solidus_friendly_promotions/actions/adjust_line_item: Discount matching line items
164
+ solidus_friendly_promotions/actions/adjust_line_item_quantity_groups: Discount matching line items based on quantity groups
165
+ solidus_friendly_promotions/calculators/distributed_amount: Distributed Amount
166
+ solidus_friendly_promotions/calculators/percent: Flat Percent
167
+ solidus_friendly_promotions/calculators/flat_rate: Flat Rate
168
+ solidus_friendly_promotions/calculators/flexi_rate: Flexible Rate
169
+ solidus_friendly_promotions/calculators/tiered_flat_rate: Tiered Flat Rate
170
+ solidus_friendly_promotions/calculators/tiered_percent: Tiered Percent
171
+ solidus_friendly_promotions/rules/first_order: First Order
172
+ solidus_friendly_promotions/rules/first_repeat_purchase_since: First Repeat Purchase Since
173
+ solidus_friendly_promotions/rules/item_total: Item Total
174
+ solidus_friendly_promotions/rules/discounted_item_total: Item Total after previous lanes
175
+ solidus_friendly_promotions/rules/landing_page: Landing Page
176
+ solidus_friendly_promotions/rules/minimum_quantity: Minimum Quantity
177
+ solidus_friendly_promotions/rules/nth_order: Nth Order
178
+ solidus_friendly_promotions/rules/one_use_per_user: One Use Per User
179
+ solidus_friendly_promotions/rules/option_value: Option Value(s)
180
+ solidus_friendly_promotions/rules/line_item_option_value: Line Item Option Value(s)
181
+ solidus_friendly_promotions/rules/product: Order Product(s)
182
+ solidus_friendly_promotions/rules/line_item_product: Line Item Product(s)
183
+ solidus_friendly_promotions/rules/taxon: Order Taxon(s)
184
+ solidus_friendly_promotions/rules/line_item_taxon: Line Item Taxon(s)
185
+ solidus_friendly_promotions/rules/user: User
186
+ solidus_friendly_promotions/rules/user_logged_in: User Logged In
187
+ solidus_friendly_promotions/rules/user_role: User Role(s)
188
+ attributes:
189
+ solidus_friendly_promotions/promotion:
190
+ active: Active
191
+ customer_label: Customer-facing label
192
+ lanes:
193
+ pre: Pre
194
+ default: Default
195
+ post: Post
196
+ solidus_friendly_promotions/promotion_action:
197
+ type: Action Type
198
+ solidus_friendly_promotions/actions/adjust_line_item:
199
+ description: Creates a promotion credit on matching line items
200
+ solidus_friendly_promotions/actions/adjust_shipment:
201
+ description: Creates a promotion credit on matching shipments
202
+ solidus_friendly_promotions/rules/first_order:
203
+ description: Must be the customer's first order
204
+ solidus_friendly_promotions/rules/first_repeat_purchase_since:
205
+ description: Available only to user who have not purchased in a while
206
+ form_text: Apply this promotion to users whose last order was more than X days ago
207
+ solidus_friendly_promotions/rules/item_total:
208
+ description: Order total meets these criteria
209
+ solidus_friendly_promotions/rules/landing_page:
210
+ description: Customer must have visited the specified page
211
+ solidus_friendly_promotions/rules/nth_order:
212
+ description: Apply a promotion to every nth order a user has completed.
213
+ form_text: 'Apply this promotion on the users Nth order: '
214
+ solidus_friendly_promotions/rules/one_use_per_user:
215
+ description: Only one use per user
216
+ solidus_friendly_promotions/rules/option_value:
217
+ description: Order includes specified product(s) with matching option value(s)
218
+ preferred_line_item_applicable: Should also apply to line items
219
+ solidus_friendly_promotions/rules/line_item_option_value:
220
+ description: Line Item has specified product with matching option value
221
+ solidus_friendly_promotions/rules/minimum_quantity:
222
+ description: Order contains minimum quantity of applicable items
223
+ solidus_friendly_promotions/rules/product:
224
+ description: Order includes specified product(s)
225
+ line_item_level_description: 'Line item matches the specified products:'
226
+ preferred_line_item_applicable: Should also apply to line items
227
+ solidus_friendly_promotions/rules/line_item_product:
228
+ description: Line item matches specified product(s)
229
+ preferred_match_policy: Match Policy
230
+ solidus_friendly_promotions/rules/store:
231
+ description: Available only to the specified stores
232
+ solidus_friendly_promotions/rules/taxon:
233
+ description: Order includes products with specified taxon(s)
234
+ preferred_line_item_applicable: Should also apply to line items
235
+ solidus_friendly_promotions/rules/line_item_taxon:
236
+ description: Line Item has product with specified taxon(s)
237
+ preferred_match_policy: Match Policy
238
+ solidus_friendly_promotions/rules/user:
239
+ description: Available only to the specified users
240
+ solidus_friendly_promotions/rules/user_logged_in:
241
+ description: Available only to logged in users
242
+ solidus_friendly_promotions/rules/user_role:
243
+ description: Order includes User with specified Role(s)
244
+ solidus_friendly_promotions/calculators/tiered_flat_rate:
245
+ preferred_base_amount: Base Amount
246
+ tiers: Tiers
247
+ solidus_friendly_promotions/calculators/tiered_percent:
248
+ preferred_base_percent: Base Percent
249
+ tiers: Tiers
250
+ errors:
251
+ models:
252
+ solidus_friendly_promotions/promotion_code:
253
+ attributes:
254
+ base:
255
+ disallowed_with_apply_automatically: Could not create promotion code on promotion that apply automatically
data/config/routes.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ SolidusFriendlyPromotions::Engine.routes.draw do
4
+ namespace :admin do
5
+ scope :friendly do
6
+ resources :promotion_categories, except: [:show]
7
+
8
+ resources :promotions do
9
+ resources :promotion_rules
10
+ resources :promotion_actions
11
+ resources :promotion_codes, only: [:index, :new, :create]
12
+ resources :promotion_code_batches, only: [:index, :new, :create] do
13
+ get "/download", to: "promotion_code_batches#download", defaults: {format: "csv"}
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ class CreatePromotions < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_promotions do |t|
4
+ t.string :description
5
+ t.datetime :expires_at, precision: nil
6
+ t.datetime :starts_at, precision: nil
7
+ t.string :name
8
+ t.integer :usage_limit
9
+ t.boolean :advertise, default: false
10
+ t.string :path
11
+ t.integer :per_code_usage_limit
12
+ t.boolean :apply_automatically, default: false
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ class CreatePromotionCategories < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_promotion_categories do |t|
4
+ t.string :name
5
+ t.string :code
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ add_reference :friendly_promotions,
11
+ :promotion_category,
12
+ foreign_key: {to_table: :friendly_promotion_categories}
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ class CreatePromotionRules < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_promotion_rules do |t|
4
+ t.references :promotion,
5
+ foreign_key: {to_table: :friendly_promotions}
6
+ t.string :type
7
+ t.text :preferences
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ class AddRuleTables < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_products_promotion_rules, force: :cascade do |t|
4
+ t.references :product, type: :integer, index: true, null: false, foreign_key: {to_table: :spree_products}
5
+ t.references :promotion_rule, index: true, null: false, foreign_key: {to_table: :friendly_promotion_rules}
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ create_table :friendly_promotion_rules_taxons, force: :cascade do |t|
11
+ t.references :taxon, type: :integer, index: true, null: false, foreign_key: {to_table: :spree_taxons}
12
+ t.references :promotion_rule, index: true, null: false, foreign_key: {to_table: :friendly_promotion_rules}
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ create_table :friendly_promotion_rules_users, force: :cascade do |t|
18
+ t.references :user, type: :integer, index: true, null: false, foreign_key: {to_table: Spree.user_class.table_name}
19
+ t.references :promotion_rule, index: true, null: false, foreign_key: {to_table: :friendly_promotion_rules}
20
+
21
+ t.timestamps
22
+ end
23
+
24
+ create_table :friendly_promotion_rules_stores do |t|
25
+ t.references :store, type: :integer, index: true, null: false, foreign_key: {to_table: :spree_stores}
26
+ t.references :promotion_rule, index: true, null: false
27
+
28
+ t.timestamps
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ class CreatePromotionActions < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_promotion_actions do |t|
4
+ t.references :promotion, index: true, null: false, foreign_key: {to_table: :friendly_promotions}
5
+ t.string :type
6
+ t.datetime :deleted_at, precision: nil
7
+ t.text :preferences
8
+ t.index [:deleted_at], name: :index_friendly_promotion_actions_on_deleted_at
9
+ t.index [:id, :type], name: :index_friendly_promotion_actions_on_id_and_type
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ class CreatePromotionCodes < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_promotion_codes, force: :cascade do |t|
4
+ t.references :promotion, null: false, index: true, foreign_key: {to_table: :friendly_promotions}
5
+ t.string :value, null: false
6
+ t.timestamps
7
+
8
+ t.index ["value"], name: "index_friendly_promotion_codes_on_value", unique: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreatePromotionCodeBatches < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :friendly_promotion_code_batches do |t|
6
+ t.references :promotion, null: false, index: true, foreign_key: {to_table: :friendly_promotions}
7
+ t.string :base_code, null: false
8
+ t.integer :number_of_codes, null: false
9
+ t.string :join_characters, null: false, default: "_"
10
+ t.string :email
11
+ t.string :error
12
+ t.string :state, default: "pending"
13
+ t.timestamps precision: 6
14
+ end
15
+
16
+ add_column(
17
+ :friendly_promotion_codes,
18
+ :promotion_code_batch_id,
19
+ :bigint
20
+ )
21
+
22
+ add_foreign_key(
23
+ :friendly_promotion_codes,
24
+ :friendly_promotion_code_batches,
25
+ column: :promotion_code_batch_id
26
+ )
27
+
28
+ add_index(
29
+ :friendly_promotion_codes,
30
+ :promotion_code_batch_id
31
+ )
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ class CreateFriendlyOrderPromotions < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_order_promotions do |t|
4
+ t.references :order, type: :integer, index: true, null: false, foreign_key: {to_table: :spree_orders}
5
+ t.references :promotion, index: true, null: false, foreign_key: {to_table: :friendly_promotions}
6
+ t.references :promotion_code, index: true, null: true, foreign_key: {to_table: :friendly_promotion_codes}
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class CreateShippingRateDiscounts < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :friendly_shipping_rate_discounts do |t|
4
+ t.references :promotion_action, type: :bigint, null: false, foreign_key: {to_table: :friendly_promotion_actions}
5
+ t.references :shipping_rate, type: :integer, null: false, foreign_key: {to_table: :spree_shipping_rates}
6
+ t.decimal :amount, precision: 10, scale: 2, null: false
7
+ t.string :label, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ class AddLaneToSolidusFriendlyPromotionsPromotions < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :friendly_promotions, :lane, :integer, null: false, default: 1
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCustomerLabelToPromotions < ActiveRecord::Migration[7.0]
4
+ def change
5
+ add_column :friendly_promotions, :customer_label, :string
6
+ end
7
+ end