solidus_promotions 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintrc.json +10 -0
  3. data/.github/stale.yml +1 -0
  4. data/MIGRATING.md +184 -0
  5. data/README.md +122 -0
  6. data/Rakefile +20 -0
  7. data/app/assets/config/solidus_promotions/manifest.js +13 -0
  8. data/app/decorators/models/solidus_promotions/adjustment_decorator.rb +11 -0
  9. data/app/decorators/models/solidus_promotions/line_item_decorator.rb +27 -0
  10. data/app/decorators/models/solidus_promotions/order_decorator.rb +42 -0
  11. data/app/decorators/models/solidus_promotions/order_recalculator_decorator.rb +15 -0
  12. data/app/decorators/models/solidus_promotions/shipment_decorator.rb +14 -0
  13. data/app/decorators/models/solidus_promotions/shipping_rate_decorator.rb +29 -0
  14. data/app/helpers/solidus_promotions/admin/benefits_helper.rb +19 -0
  15. data/app/helpers/solidus_promotions/admin/conditions_helper.rb +14 -0
  16. data/app/helpers/solidus_promotions/admin/promotions_helper.rb +15 -0
  17. data/app/javascript/backend/solidus_promotions/controllers/application.js +9 -0
  18. data/app/javascript/backend/solidus_promotions/controllers/calculator_tiers_controller.js +37 -0
  19. data/app/javascript/backend/solidus_promotions/controllers/flash_controller.js +10 -0
  20. data/app/javascript/backend/solidus_promotions/controllers/index.js +8 -0
  21. data/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js +62 -0
  22. data/app/javascript/backend/solidus_promotions/web_components/number_with_currency.js +35 -0
  23. data/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js +52 -0
  24. data/app/javascript/backend/solidus_promotions/web_components/product_picker.js +7 -0
  25. data/app/javascript/backend/solidus_promotions/web_components/select_two.js +11 -0
  26. data/app/javascript/backend/solidus_promotions/web_components/taxon_picker.js +7 -0
  27. data/app/javascript/backend/solidus_promotions/web_components/user_picker.js +7 -0
  28. data/app/javascript/backend/solidus_promotions/web_components/variant_picker.js +7 -0
  29. data/app/javascript/backend/solidus_promotions.js +11 -0
  30. data/app/jobs/solidus_promotions/promotion_code_batch_job.rb +26 -0
  31. data/app/mailers/solidus_promotions/promotion_code_batch_mailer.rb +15 -0
  32. data/app/models/concerns/solidus_promotions/benefits/line_item_benefit.rb +15 -0
  33. data/app/models/concerns/solidus_promotions/benefits/order_benefit.rb +15 -0
  34. data/app/models/concerns/solidus_promotions/benefits/shipment_benefit.rb +15 -0
  35. data/app/models/concerns/solidus_promotions/calculators/promotion_calculator.rb +11 -0
  36. data/app/models/concerns/solidus_promotions/conditions/line_item_applicable_order_level_condition.rb +23 -0
  37. data/app/models/concerns/solidus_promotions/conditions/line_item_level_condition.rb +15 -0
  38. data/app/models/concerns/solidus_promotions/conditions/order_level_condition.rb +15 -0
  39. data/app/models/concerns/solidus_promotions/conditions/shipment_level_condition.rb +15 -0
  40. data/app/models/concerns/solidus_promotions/discountable_amount.rb +21 -0
  41. data/app/models/solidus_promotions/benefit.rb +123 -0
  42. data/app/models/solidus_promotions/benefits/adjust_line_item.rb +13 -0
  43. data/app/models/solidus_promotions/benefits/adjust_line_item_quantity_groups.rb +107 -0
  44. data/app/models/solidus_promotions/benefits/adjust_shipment.rb +13 -0
  45. data/app/models/solidus_promotions/benefits/create_discounted_item.rb +49 -0
  46. data/app/models/solidus_promotions/calculators/distributed_amount.rb +31 -0
  47. data/app/models/solidus_promotions/calculators/flat_rate.rb +23 -0
  48. data/app/models/solidus_promotions/calculators/flexi_rate.rb +26 -0
  49. data/app/models/solidus_promotions/calculators/percent.rb +19 -0
  50. data/app/models/solidus_promotions/calculators/tiered_flat_rate.rb +58 -0
  51. data/app/models/solidus_promotions/calculators/tiered_percent.rb +68 -0
  52. data/app/models/solidus_promotions/calculators/tiered_percent_on_eligible_item_quantity.rb +40 -0
  53. data/app/models/solidus_promotions/condition.rb +61 -0
  54. data/app/models/solidus_promotions/condition_product.rb +8 -0
  55. data/app/models/solidus_promotions/condition_store.rb +8 -0
  56. data/app/models/solidus_promotions/condition_taxon.rb +8 -0
  57. data/app/models/solidus_promotions/condition_user.rb +8 -0
  58. data/app/models/solidus_promotions/conditions/discounted_item_total.rb +22 -0
  59. data/app/models/solidus_promotions/conditions/first_order.rb +31 -0
  60. data/app/models/solidus_promotions/conditions/first_repeat_purchase_since.rb +31 -0
  61. data/app/models/solidus_promotions/conditions/item_total.rb +75 -0
  62. data/app/models/solidus_promotions/conditions/line_item_option_value.rb +37 -0
  63. data/app/models/solidus_promotions/conditions/line_item_product.rb +56 -0
  64. data/app/models/solidus_promotions/conditions/line_item_taxon.rb +59 -0
  65. data/app/models/solidus_promotions/conditions/minimum_quantity.rb +42 -0
  66. data/app/models/solidus_promotions/conditions/nth_order.rb +40 -0
  67. data/app/models/solidus_promotions/conditions/one_use_per_user.rb +25 -0
  68. data/app/models/solidus_promotions/conditions/option_value.rb +28 -0
  69. data/app/models/solidus_promotions/conditions/product.rb +85 -0
  70. data/app/models/solidus_promotions/conditions/shipping_method.rb +19 -0
  71. data/app/models/solidus_promotions/conditions/store.rb +26 -0
  72. data/app/models/solidus_promotions/conditions/taxon.rb +98 -0
  73. data/app/models/solidus_promotions/conditions/user.rb +35 -0
  74. data/app/models/solidus_promotions/conditions/user_logged_in.rb +16 -0
  75. data/app/models/solidus_promotions/conditions/user_role.rb +42 -0
  76. data/app/models/solidus_promotions/distributed_amounts_handler.rb +39 -0
  77. data/app/models/solidus_promotions/eligibility_result.rb +5 -0
  78. data/app/models/solidus_promotions/eligibility_results.rb +47 -0
  79. data/app/models/solidus_promotions/item_discount.rb +21 -0
  80. data/app/models/solidus_promotions/migration_support/order_promotion_syncer.rb +54 -0
  81. data/app/models/solidus_promotions/order_adjuster/choose_discounts.rb +21 -0
  82. data/app/models/solidus_promotions/order_adjuster/discount_order.rb +93 -0
  83. data/app/models/solidus_promotions/order_adjuster/load_promotions.rb +53 -0
  84. data/app/models/solidus_promotions/order_adjuster/persist_discounted_order.rb +79 -0
  85. data/app/models/solidus_promotions/order_adjuster.rb +33 -0
  86. data/app/models/solidus_promotions/order_promotion.rb +23 -0
  87. data/app/models/solidus_promotions/permission_sets/solidus_promotion_management.rb +15 -0
  88. data/app/models/solidus_promotions/promotion.rb +163 -0
  89. data/app/models/solidus_promotions/promotion_advertiser.rb +10 -0
  90. data/app/models/solidus_promotions/promotion_category.rb +9 -0
  91. data/app/models/solidus_promotions/promotion_code/batch_builder.rb +73 -0
  92. data/app/models/solidus_promotions/promotion_code.rb +56 -0
  93. data/app/models/solidus_promotions/promotion_code_batch.rb +25 -0
  94. data/app/models/solidus_promotions/promotion_finder.rb +10 -0
  95. data/app/models/solidus_promotions/promotion_handler/coupon.rb +113 -0
  96. data/app/models/solidus_promotions/promotion_handler/page.rb +30 -0
  97. data/app/models/solidus_promotions/shipping_rate_discount.rb +11 -0
  98. data/app/subscribers/solidus_promotions/order_promotion_subscriber.rb +20 -0
  99. data/bin/rails +13 -0
  100. data/config/importmap.rb +14 -0
  101. data/config/locales/en.yml +376 -0
  102. data/config/locales/promotion_categories.en.yml +6 -0
  103. data/config/locales/promotions.en.yml +6 -0
  104. data/config/routes.rb +38 -0
  105. data/db/migrate/20230703101637_create_promotions.rb +25 -0
  106. data/db/migrate/20230703113625_create_promotion_benefits.rb +15 -0
  107. data/db/migrate/20230703141116_create_promotion_categories.rb +14 -0
  108. data/db/migrate/20230703143943_create_promotion_conditions.rb +12 -0
  109. data/db/migrate/20230704083830_add_condition_join_tables.rb +31 -0
  110. data/db/migrate/20230704102444_create_promotion_codes.rb +11 -0
  111. data/db/migrate/20230704102656_create_promotion_code_batches.rb +34 -0
  112. data/db/migrate/20230705171556_create_order_promotions.rb +11 -0
  113. data/db/migrate/20230725074235_create_shipping_rate_discounts.rb +12 -0
  114. data/db/migrate/20231011100059_add_db_comments_to_order_promotions.rb +61 -0
  115. data/db/migrate/20231011120928_add_db_comments_to_condition_taxons.rb +54 -0
  116. data/db/migrate/20231011131324_add_db_comments_to_conditions.rb +60 -0
  117. data/db/migrate/20231011142040_add_db_comments_to_condition_users.rb +53 -0
  118. data/db/migrate/20231011155822_add_db_comments_to_promotions.rb +123 -0
  119. data/db/migrate/20231011163030_add_db_comments_to_promotion_codes.rb +60 -0
  120. data/db/migrate/20231011173312_add_db_comments_to_promotion_code_batches.rb +91 -0
  121. data/db/migrate/20231011184205_add_db_comments_to_condition_stores.rb +53 -0
  122. data/db/migrate/20231011190222_add_db_comments_to_benefits.rb +61 -0
  123. data/db/migrate/20231012020928_add_db_comments_to_condition_products.rb +52 -0
  124. data/db/migrate/20231012120928_add_db_comments_to_promotion_categories.rb +52 -0
  125. data/db/migrate/20231104135812_add_managed_by_order_benefit_to_line_items.rb +5 -0
  126. data/lib/components/admin/solidus_admin/orders/show/adjustments/index/source/solidus_promotions_benefit/component.rb +17 -0
  127. data/lib/components/admin/solidus_promotions/orders/index/component.rb +15 -0
  128. data/lib/components/admin/solidus_promotions/orders/index/component.yml +3 -0
  129. data/lib/components/admin/solidus_promotions/promotion_categories/index/component.rb +60 -0
  130. data/lib/components/admin/solidus_promotions/promotions/index/component.rb +108 -0
  131. data/lib/components/admin/solidus_promotions/promotions/index/component.yml +10 -0
  132. data/lib/controllers/admin/solidus_promotions/promotion_categories_controller.rb +29 -0
  133. data/lib/controllers/admin/solidus_promotions/promotions_controller.rb +46 -0
  134. data/lib/controllers/backend/solidus_promotions/admin/base_controller.rb +15 -0
  135. data/lib/controllers/backend/solidus_promotions/admin/benefits_controller.rb +85 -0
  136. data/lib/controllers/backend/solidus_promotions/admin/conditions_controller.rb +69 -0
  137. data/lib/controllers/backend/solidus_promotions/admin/promotion_categories_controller.rb +13 -0
  138. data/lib/controllers/backend/solidus_promotions/admin/promotion_code_batches_controller.rb +42 -0
  139. data/lib/controllers/backend/solidus_promotions/admin/promotion_codes_controller.rb +58 -0
  140. data/lib/controllers/backend/solidus_promotions/admin/promotions_controller.rb +65 -0
  141. data/lib/generators/solidus_promotions/install/install_generator.rb +56 -0
  142. data/lib/generators/solidus_promotions/install/templates/initializer.rb +6 -0
  143. data/lib/solidus_promotions/configuration.rb +125 -0
  144. data/lib/solidus_promotions/engine.rb +115 -0
  145. data/lib/solidus_promotions/migrate_adjustments.rb +62 -0
  146. data/lib/solidus_promotions/migrate_order_promotions.rb +73 -0
  147. data/lib/solidus_promotions/promotion_map.rb +126 -0
  148. data/lib/solidus_promotions/promotion_migrator.rb +103 -0
  149. data/lib/solidus_promotions/testing_support/factories/completed_order_with_solidus_promotion_factory.rb +20 -0
  150. data/lib/solidus_promotions/testing_support/factories/solidus_order_promotion_factory.rb +8 -0
  151. data/lib/solidus_promotions/testing_support/factories/solidus_promotion_category_factory.rb +7 -0
  152. data/lib/solidus_promotions/testing_support/factories/solidus_promotion_code_factory.rb +8 -0
  153. data/lib/solidus_promotions/testing_support/factories/solidus_promotion_factory.rb +65 -0
  154. data/lib/solidus_promotions/testing_support/factories/solidus_shipping_rate_discount_factory.rb +14 -0
  155. data/lib/solidus_promotions/testing_support/factory_bot.rb +30 -0
  156. data/lib/solidus_promotions.rb +37 -0
  157. data/lib/tasks/solidus_promotions/migrate_adjustments.rake +17 -0
  158. data/lib/tasks/solidus_promotions/migrate_existing_promotions.rake +12 -0
  159. data/lib/tasks/solidus_promotions/migrate_order_promotions.rake +17 -0
  160. data/lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_line_item.html.erb +6 -0
  161. data/lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_line_item_quantity_groups.html.erb +13 -0
  162. data/lib/views/backend/solidus_promotions/admin/benefit_fields/_adjust_shipment.html.erb +6 -0
  163. data/lib/views/backend/solidus_promotions/admin/benefit_fields/_calculator_fields.erb +11 -0
  164. data/lib/views/backend/solidus_promotions/admin/benefit_fields/_create_discounted_item.html.erb +21 -0
  165. data/lib/views/backend/solidus_promotions/admin/benefits/_benefit.html.erb +50 -0
  166. data/lib/views/backend/solidus_promotions/admin/benefits/_calculator_select.html.erb +16 -0
  167. data/lib/views/backend/solidus_promotions/admin/benefits/_form.html.erb +3 -0
  168. data/lib/views/backend/solidus_promotions/admin/benefits/_new_benefit.html.erb +33 -0
  169. data/lib/views/backend/solidus_promotions/admin/benefits/_type_select.html.erb +16 -0
  170. data/lib/views/backend/solidus_promotions/admin/benefits/edit.html.erb +19 -0
  171. data/lib/views/backend/solidus_promotions/admin/benefits/new.html.erb +1 -0
  172. data/lib/views/backend/solidus_promotions/admin/calculator_fields/_default_fields.html.erb +6 -0
  173. data/lib/views/backend/solidus_promotions/admin/calculator_fields/distributed_amount/_fields.html.erb +18 -0
  174. data/lib/views/backend/solidus_promotions/admin/calculator_fields/flat_rate/_fields.html.erb +6 -0
  175. data/lib/views/backend/solidus_promotions/admin/calculator_fields/flexi_rate/_fields.html.erb +24 -0
  176. data/lib/views/backend/solidus_promotions/admin/calculator_fields/percent/_fields.html.erb +6 -0
  177. data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_flat_rate/_fields.html.erb +32 -0
  178. data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_flat_rate/_tier_fields.html.erb +31 -0
  179. data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent/_fields.html.erb +47 -0
  180. data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent/_tier_fields.html.erb +33 -0
  181. data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent_on_eligible_item_quantity/_fields.html.erb +36 -0
  182. data/lib/views/backend/solidus_promotions/admin/calculator_fields/tiered_percent_on_eligible_item_quantity/_tier_fields.html.erb +35 -0
  183. data/lib/views/backend/solidus_promotions/admin/condition_fields/_first_order.html.erb +3 -0
  184. data/lib/views/backend/solidus_promotions/admin/condition_fields/_first_repeat_purchase_since.html.erb +7 -0
  185. data/lib/views/backend/solidus_promotions/admin/condition_fields/_item_total.html.erb +15 -0
  186. data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb +25 -0
  187. data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_product.html.erb +21 -0
  188. data/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_taxon.html.erb +17 -0
  189. data/lib/views/backend/solidus_promotions/admin/condition_fields/_minimum_quantity.html.erb +5 -0
  190. data/lib/views/backend/solidus_promotions/admin/condition_fields/_nth_order.html.erb +15 -0
  191. data/lib/views/backend/solidus_promotions/admin/condition_fields/_one_use_per_user.html.erb +3 -0
  192. data/lib/views/backend/solidus_promotions/admin/condition_fields/_option_value.html.erb +63 -0
  193. data/lib/views/backend/solidus_promotions/admin/condition_fields/_product.html.erb +27 -0
  194. data/lib/views/backend/solidus_promotions/admin/condition_fields/_shipping_method.html.erb +10 -0
  195. data/lib/views/backend/solidus_promotions/admin/condition_fields/_store.html.erb +9 -0
  196. data/lib/views/backend/solidus_promotions/admin/condition_fields/_taxon.html.erb +27 -0
  197. data/lib/views/backend/solidus_promotions/admin/condition_fields/_user.html.erb +7 -0
  198. data/lib/views/backend/solidus_promotions/admin/condition_fields/_user_logged_in.html.erb +3 -0
  199. data/lib/views/backend/solidus_promotions/admin/condition_fields/_user_role.html.erb +15 -0
  200. data/lib/views/backend/solidus_promotions/admin/condition_fields/line_item_option_value/_option_value_fields.html.erb +21 -0
  201. data/lib/views/backend/solidus_promotions/admin/conditions/_condition.html.erb +26 -0
  202. data/lib/views/backend/solidus_promotions/admin/conditions/_new_condition.html.erb +26 -0
  203. data/lib/views/backend/solidus_promotions/admin/conditions/_type_select.html.erb +20 -0
  204. data/lib/views/backend/solidus_promotions/admin/conditions/new.html.erb +1 -0
  205. data/lib/views/backend/solidus_promotions/admin/promotion_categories/_form.html.erb +14 -0
  206. data/lib/views/backend/solidus_promotions/admin/promotion_categories/edit.html.erb +10 -0
  207. data/lib/views/backend/solidus_promotions/admin/promotion_categories/index.html.erb +47 -0
  208. data/lib/views/backend/solidus_promotions/admin/promotion_categories/new.html.erb +10 -0
  209. data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/_form_fields.html.erb +22 -0
  210. data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/download.csv.ruby +8 -0
  211. data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/index.html.erb +65 -0
  212. data/lib/views/backend/solidus_promotions/admin/promotion_code_batches/new.html.erb +8 -0
  213. data/lib/views/backend/solidus_promotions/admin/promotion_codes/index.csv.ruby +8 -0
  214. data/lib/views/backend/solidus_promotions/admin/promotion_codes/index.html.erb +32 -0
  215. data/lib/views/backend/solidus_promotions/admin/promotion_codes/new.html.erb +31 -0
  216. data/lib/views/backend/solidus_promotions/admin/promotions/_form.html.erb +124 -0
  217. data/lib/views/backend/solidus_promotions/admin/promotions/_table.html.erb +57 -0
  218. data/lib/views/backend/solidus_promotions/admin/promotions/_table_filter.html.erb +78 -0
  219. data/lib/views/backend/solidus_promotions/admin/promotions/edit.html.erb +41 -0
  220. data/lib/views/backend/solidus_promotions/admin/promotions/index.html.erb +23 -0
  221. data/lib/views/backend/solidus_promotions/admin/promotions/new.html.erb +9 -0
  222. data/lib/views/backend/solidus_promotions/admin/shared/_number_with_currency.html.erb +20 -0
  223. data/lib/views/backend/solidus_promotions/admin/shared/_promotion_sub_menu.html.erb +14 -0
  224. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_boolean.html.erb +14 -0
  225. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_decimal.html.erb +12 -0
  226. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_encrypted_string.html.erb +12 -0
  227. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_integer.html.erb +12 -0
  228. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_password.html.erb +12 -0
  229. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_string.html.erb +12 -0
  230. data/lib/views/backend/solidus_promotions/admin/shared/preference_fields/_text.html.erb +12 -0
  231. data/lib/views/backend/solidus_promotions/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
  232. data/lib/views/backend/solidus_promotions/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
  233. data/solidus_promotions.gemspec +33 -0
  234. metadata +366 -0
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPromotions
4
+ # This constants maps rules and actions from the legacy promotion system to conditions and benefits, respectively.
5
+ # This is used to migrate promotions from the legacy promotion system to the new one.
6
+ # If you have custom rules or actions, you can add them to this hash like so:
7
+
8
+ # # lib/my_store/promotion_map.rb
9
+ # require "solidus_promotions/promotion_map"
10
+ #
11
+ # MyStore::PROMOTION_MAP = SolidusPromotions::PROMOTION_MAP.merge(
12
+ # conditions: {
13
+ # Spree::Promotion::Rules::MyCustomRule => MyStore::Conditions::MyCustomCondition
14
+ # },
15
+ # actions: {
16
+ # Spree::Promotion::Actions::MyCustomAction => MyStore::Benefits::MyCustomAction
17
+ # }
18
+ # )
19
+
20
+ # And then use it in a custom rake task like so:
21
+
22
+ # # lib/rake/my_store.rake
23
+ # namespace :my_store do
24
+ # desc "Migrate Spree Promotions to Friendly Promotions using a map"
25
+ # task migrate_existing_promotions: :environment do
26
+ # require "solidus_promotions/promotion_migrator"
27
+ # require "my_store/promotion_map"
28
+ # SolidusPromotions::PromotionMigrator.new(MyStore::PROMOTION_MAP).call
29
+ # end
30
+ # end
31
+
32
+ # Note that the key in both the conditions and actions hash should be the class of the rule or action you want to map, while the value can be either
33
+ # a class or a lambda that returns a class. If you use a lambda, it will be called with the old action or rule as an argument.
34
+ PROMOTION_MAP = {
35
+ conditions: {
36
+ Spree::Promotion::Rules::ItemTotal =>
37
+ SolidusPromotions::Conditions::ItemTotal,
38
+ Spree::Promotion::Rules::Product =>
39
+ SolidusPromotions::Conditions::Product,
40
+ Spree::Promotion::Rules::User =>
41
+ SolidusPromotions::Conditions::User,
42
+ Spree::Promotion::Rules::FirstOrder =>
43
+ SolidusPromotions::Conditions::FirstOrder,
44
+ Spree::Promotion::Rules::UserLoggedIn =>
45
+ SolidusPromotions::Conditions::UserLoggedIn,
46
+ Spree::Promotion::Rules::OneUsePerUser =>
47
+ SolidusPromotions::Conditions::OneUsePerUser,
48
+ Spree::Promotion::Rules::Taxon =>
49
+ SolidusPromotions::Conditions::Taxon,
50
+ Spree::Promotion::Rules::NthOrder =>
51
+ SolidusPromotions::Conditions::NthOrder,
52
+ Spree::Promotion::Rules::OptionValue =>
53
+ SolidusPromotions::Conditions::OptionValue,
54
+ Spree::Promotion::Rules::FirstRepeatPurchaseSince =>
55
+ SolidusPromotions::Conditions::FirstRepeatPurchaseSince,
56
+ Spree::Promotion::Rules::UserRole =>
57
+ SolidusPromotions::Conditions::UserRole,
58
+ Spree::Promotion::Rules::Store =>
59
+ SolidusPromotions::Conditions::Store
60
+ },
61
+ actions: {
62
+ Spree::Promotion::Actions::CreateAdjustment => ->(old_action) {
63
+ calculator = case old_action.calculator
64
+ when Spree::Calculator::FlatRate
65
+ SolidusPromotions::Calculators::DistributedAmount.new(preferences: old_action.calculator.preferences)
66
+ when Spree::Calculator::FlatPercentItemTotal
67
+ SolidusPromotions::Calculators::Percent.new(preferred_percent: old_action.calculator.preferred_flat_percent)
68
+ end
69
+
70
+ SolidusPromotions::Benefits::AdjustLineItem.new(
71
+ calculator: calculator
72
+ )
73
+ },
74
+ Spree::Promotion::Actions::CreateItemAdjustments => ->(old_action) {
75
+ preferences = old_action.calculator.preferences
76
+ calculator = case old_action.calculator
77
+ when Spree::Calculator::FlatRate
78
+ SolidusPromotions::Calculators::FlatRate.new(preferences: preferences)
79
+ when Spree::Calculator::PercentOnLineItem
80
+ SolidusPromotions::Calculators::Percent.new(preferences: preferences)
81
+ when Spree::Calculator::FlexiRate
82
+ SolidusPromotions::Calculators::FlexiRate.new(preferences: preferences)
83
+ when Spree::Calculator::DistributedAmount
84
+ SolidusPromotions::Calculators::DistributedAmount.new(preferences: preferences)
85
+ when Spree::Calculator::TieredFlatRate
86
+ SolidusPromotions::Calculators::TieredFlatRate.new(preferences: preferences)
87
+ when Spree::Calculator::TieredPercent
88
+ SolidusPromotions::Calculators::TieredPercent.new(preferences: preferences)
89
+ end
90
+
91
+ SolidusPromotions::Benefits::AdjustLineItem.new(
92
+ calculator: calculator
93
+ )
94
+ },
95
+ Spree::Promotion::Actions::CreateQuantityAdjustments => ->(old_action) {
96
+ preferences = old_action.calculator.preferences
97
+ calculator = case old_action.calculator
98
+ when Spree::Calculator::FlatRate
99
+ SolidusPromotions::Calculators::FlatRate.new(preferences: preferences)
100
+ when Spree::Calculator::PercentOnLineItem
101
+ SolidusPromotions::Calculators::Percent.new(preferences: preferences)
102
+ when Spree::Calculator::FlexiRate
103
+ SolidusPromotions::Calculators::FlexiRate.new(preferences: preferences)
104
+ when Spree::Calculator::DistributedAmount
105
+ SolidusPromotions::Calculators::DistributedAmount.new(preferences: preferences)
106
+ when Spree::Calculator::TieredFlatRate
107
+ SolidusPromotions::Calculators::TieredFlatRate.new(preferences: preferences)
108
+ when Spree::Calculator::TieredPercent
109
+ SolidusPromotions::Calculators::TieredPercent.new(preferences: preferences)
110
+ end
111
+
112
+ SolidusPromotions::Benefits::AdjustLineItemQuantityGroups.new(
113
+ preferred_group_size: old_action.preferred_group_size,
114
+ calculator: calculator
115
+ )
116
+ },
117
+ Spree::Promotion::Actions::FreeShipping => ->(_old_action) {
118
+ SolidusPromotions::Benefits::AdjustShipment.new(
119
+ calculator: SolidusPromotions::Calculators::Percent.new(
120
+ preferred_percent: 100
121
+ )
122
+ )
123
+ }
124
+ }
125
+ }
126
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPromotions
4
+ class PromotionMigrator
5
+ PROMOTION_IGNORED_ATTRIBUTES = ["id", "type", "promotion_category_id", "promotion_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
+ SolidusPromotions::PromotionCategory.destroy_all
15
+ Spree::PromotionCategory.all.find_each do |promotion_category|
16
+ SolidusPromotions::PromotionCategory.create!(promotion_category.attributes.except("id"))
17
+ end
18
+
19
+ SolidusPromotions::Promotion.destroy_all
20
+ Spree::Promotion.all.find_each do |promotion|
21
+ new_promotion = copy_promotion(promotion)
22
+ if promotion.promotion_category&.name.present?
23
+ new_promotion.category = SolidusPromotions::PromotionCategory.find_by(
24
+ name: promotion.promotion_category.name
25
+ )
26
+ end
27
+ new_promotion.benefits = promotion.actions.flat_map do |old_promotion_action|
28
+ generate_new_benefits(old_promotion_action)&.tap do |new_promotion_action|
29
+ new_promotion_action.original_promotion_action = old_promotion_action
30
+ new_promotion_action.conditions = promotion.rules.flat_map do |old_promotion_rule|
31
+ generate_new_promotion_conditions(old_promotion_rule)
32
+ end
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 solidus_promotions_promotion_code_batches (promotion_id, base_code, number_of_codes, email, error, state, created_at, updated_at, join_characters)
46
+ SELECT solidus_promotions_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 solidus_promotions_promotions ON spree_promotions.id = solidus_promotions_promotions.original_promotion_id
50
+ WHERE spree_promotion_code_batches.promotion_id = #{new_promotion.original_promotion_id};
51
+ SQL
52
+ SolidusPromotions::PromotionCodeBatch.connection.execute(sql)
53
+ end
54
+
55
+ def copy_promotion_codes(new_promotion)
56
+ sql = <<~SQL
57
+ INSERT INTO solidus_promotions_promotion_codes (promotion_id, promotion_code_batch_id, value, created_at, updated_at)
58
+ SELECT solidus_promotions_promotions.id AS promotion_id, solidus_promotions_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 solidus_promotions_promotion_code_batches ON solidus_promotions_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 solidus_promotions_promotions ON spree_promotions.id = solidus_promotions_promotions.original_promotion_id
64
+ WHERE spree_promotion_codes.promotion_id = #{new_promotion.original_promotion_id};
65
+ SQL
66
+ SolidusPromotions::PromotionCode.connection.execute(sql)
67
+ end
68
+
69
+ def copy_promotion(old_promotion)
70
+ SolidusPromotions::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_benefits(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_conditions(old_promotion_rule)
88
+ new_promo_condition_class = promotion_map[:conditions][old_promotion_rule.class]
89
+ if new_promo_condition_class.nil?
90
+ puts("#{old_promotion_rule.class} is not supported")
91
+ []
92
+ elsif new_promo_condition_class.respond_to?(:call)
93
+ new_promo_condition_class.call(old_promotion_rule)
94
+ else
95
+ new_condition = new_promo_condition_class.new(old_promotion_rule.attributes.except(*PROMOTION_IGNORED_ATTRIBUTES))
96
+ new_condition.preload_relations.each do |relation|
97
+ new_condition.send(:"#{relation}=", old_promotion_rule.send(relation))
98
+ end
99
+ [new_condition]
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :completed_order_with_solidus_promotion, parent: :order_with_line_items do
5
+ transient do
6
+ completed_at { Time.current }
7
+ promotion { nil }
8
+ end
9
+
10
+ after(:create) do |order, evaluator|
11
+ promotion = evaluator.promotion || create(:solidus_promotion, code: "test")
12
+ promotion_code = promotion.codes.first || create(:solidus_promotion_code, promotion: promotion)
13
+
14
+ order.solidus_order_promotions.create!(promotion: promotion, promotion_code: promotion_code)
15
+ order.recalculate
16
+ order.update_column(:completed_at, evaluator.completed_at)
17
+ order.update_column(:state, "complete")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :solidus_order_promotion, class: "SolidusPromotions::OrderPromotion" do
5
+ association :order, factory: :order
6
+ association :promotion, factory: :solidus_promotion
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :solidus_promotion_category, class: "SolidusPromotions::PromotionCategory" do
5
+ name { "Promotion Category" }
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :solidus_promotion_code, class: "SolidusPromotions::PromotionCode" do
5
+ association :promotion, factory: :solidus_promotion
6
+ sequence(:value) { |i| "code#{i}" }
7
+ end
8
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :solidus_promotion, class: "SolidusPromotions::Promotion" do
5
+ name { "Promo" }
6
+ customer_label { "Because we like you" }
7
+
8
+ transient do
9
+ code { nil }
10
+ end
11
+ before(:create) do |promotion, evaluator|
12
+ if evaluator.code
13
+ promotion.codes << build(:solidus_promotion_code, promotion: promotion, value: evaluator.code)
14
+ end
15
+ end
16
+
17
+ trait :with_adjustable_benefit do
18
+ transient do
19
+ preferred_amount { 10 }
20
+ calculator_class { SolidusPromotions::Calculators::FlatRate }
21
+ promotion_benefit_class { SolidusPromotions::Benefits::AdjustLineItem }
22
+ conditions { [] }
23
+ end
24
+
25
+ after(:create) do |promotion, evaluator|
26
+ calculator = evaluator.calculator_class.new
27
+ calculator.preferred_amount = evaluator.preferred_amount
28
+ evaluator.promotion_benefit_class.create!(calculator: calculator, promotion: promotion, conditions: evaluator.conditions)
29
+ end
30
+ end
31
+
32
+ factory :solidus_promotion_with_benefit_adjustment, traits: [:with_adjustable_benefit]
33
+
34
+ trait :with_line_item_adjustment do
35
+ transient do
36
+ adjustment_rate { 10 }
37
+ end
38
+
39
+ with_adjustable_benefit
40
+ preferred_amount { adjustment_rate }
41
+ end
42
+
43
+ factory :solidus_promotion_with_item_adjustment, traits: [:with_line_item_adjustment]
44
+
45
+ trait :with_free_shipping do
46
+ after(:create) do |promotion|
47
+ calculator = SolidusPromotions::Calculators::Percent.new(preferred_percent: 100)
48
+
49
+ SolidusPromotions::Benefits::AdjustShipment.create!(promotion: promotion, calculator: calculator)
50
+ end
51
+ end
52
+
53
+ trait :with_order_adjustment do
54
+ transient do
55
+ weighted_order_adjustment_amount { 10 }
56
+ end
57
+
58
+ with_adjustable_benefit
59
+ preferred_amount { weighted_order_adjustment_amount }
60
+ calculator_class { SolidusPromotions::Calculators::DistributedAmount }
61
+ end
62
+
63
+ factory :solidus_promotion_with_order_adjustment, traits: [:with_order_adjustment]
64
+ end
65
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :solidus_shipping_rate_discount, class: "SolidusPromotions::ShippingRateDiscount" do
5
+ amount { BigDecimal("-4.00") }
6
+ shipping_rate
7
+ benefit do
8
+ promotion = create(:solidus_promotion, name: "10% off shipping!", customer_label: "10% off")
9
+ ten_percent = SolidusPromotions::Calculators::Percent.new(preferred_percent: 10)
10
+ SolidusPromotions::Benefits::AdjustShipment.create!(promotion: promotion, calculator: ten_percent)
11
+ end
12
+ label { "10% off" }
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "factory_bot"
4
+ begin
5
+ require "factory_bot_rails"
6
+ rescue LoadError
7
+ end
8
+
9
+ module SolidusPromotions
10
+ module TestingSupport
11
+ module FactoryBot
12
+ SEQUENCES = ["#{::SolidusPromotions::Engine.root}/lib/solidus_promotions/testing_support/sequences.rb"]
13
+ FACTORIES = Dir["#{::SolidusPromotions::Engine.root}/lib/solidus_promotions/testing_support/factories/**/*_factory.rb"].sort
14
+ PATHS = SEQUENCES + FACTORIES
15
+
16
+ def self.definition_file_paths
17
+ @paths ||= PATHS.map { |path| path.sub(/.rb\z/, "") }
18
+ end
19
+
20
+ def self.add_definitions!
21
+ ::FactoryBot.definition_file_paths.unshift(*definition_file_paths).uniq!
22
+ end
23
+
24
+ def self.add_paths_and_load!
25
+ add_definitions!
26
+ ::FactoryBot.reload
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "solidus_core"
4
+ require "solidus_support"
5
+ require "turbo-rails"
6
+ require "importmap-rails"
7
+ require "stimulus-rails"
8
+ require "ransack-enum"
9
+
10
+ # We carry controllers and views for both the traditional backend
11
+ # and the new Solidus Admin interface, but we want to continue to function
12
+ # if either of them are not present. If they are present,
13
+ # however, they need to load before us.
14
+ begin
15
+ require "solidus_backend"
16
+ rescue LoadError
17
+ # Solidus backend is not available
18
+ end
19
+
20
+ begin
21
+ require "solidus_admin"
22
+ rescue LoadError
23
+ # Solidus Admin is not available
24
+ end
25
+
26
+ module SolidusPromotions
27
+ def self.table_name_prefix
28
+ "solidus_promotions_"
29
+ end
30
+
31
+ # JS Importmap instance
32
+ singleton_class.attr_accessor :importmap
33
+ self.importmap = Importmap::Map.new
34
+ end
35
+
36
+ require "solidus_promotions/configuration"
37
+ require "solidus_promotions/engine"
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :solidus_promotions do
4
+ namespace :migrate_adjustments do
5
+ desc "Migrate adjustments with Spree::Benefit sources to SolidusPromotions::Benefit sources"
6
+ task up: :environment do
7
+ require "solidus_promotions/migrate_adjustments"
8
+ SolidusPromotions::MigrateAdjustments.up
9
+ end
10
+
11
+ desc "Migrate adjustments with SolidusPromotions::Benefit sources to Spree::Benefit sources"
12
+ task down: :environment do
13
+ require "solidus_promotions/migrate_adjustments"
14
+ SolidusPromotions::MigrateAdjustments.down
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "solidus_promotions/promotion_migrator"
4
+
5
+ namespace :solidus_promotions do
6
+ desc "Migrate Spree Promotions to Friendly Promotions using a map"
7
+ task migrate_existing_promotions: :environment do
8
+ require "solidus_promotions/promotion_map"
9
+
10
+ SolidusPromotions::PromotionMigrator.new(SolidusPromotions::PROMOTION_MAP).call
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :solidus_promotions do
4
+ namespace :migrate_order_promotions do
5
+ desc "Migrate order promotions from Spree::OrderPromotion sources to SolidusPromotions::FriendlyOrderPromotion sources"
6
+ task up: :environment do
7
+ require "solidus_promotions/migrate_order_promotions"
8
+ SolidusPromotions::MigrateOrderPromotions.up
9
+ end
10
+
11
+ desc "Migrate order promotions from SolidusPromotions::FriendlyOrderPromotion sources to Spree::OrderPromotion sources"
12
+ task down: :environment do
13
+ require "solidus_promotions/migrate_order_promotions"
14
+ SolidusPromotions::MigrateOrderPromotions.down
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ <%= render(
2
+ "solidus_promotions/admin/benefit_fields/calculator_fields",
3
+ benefit: benefit,
4
+ param_prefix: param_prefix,
5
+ form: form
6
+ ) %>
@@ -0,0 +1,13 @@
1
+ <%= fields_for param_prefix, benefit do |form| %>
2
+ <div class="form-group">
3
+ <%= form.label :preferred_group_size %>
4
+ <%= form.number_field :preferred_group_size, class: "fullwidth", min: 1 %>
5
+ </div>
6
+ <% end %>
7
+
8
+ <%= render(
9
+ "solidus_promotions/admin/benefit_fields/calculator_fields",
10
+ benefit: benefit,
11
+ param_prefix: param_prefix,
12
+ form: form
13
+ ) %>
@@ -0,0 +1,6 @@
1
+ <%= render(
2
+ "solidus_promotions/admin/benefit_fields/calculator_fields",
3
+ benefit: benefit,
4
+ param_prefix: param_prefix,
5
+ form: form
6
+ ) %>
@@ -0,0 +1,11 @@
1
+
2
+ <% calculator = benefit.calculator %>
3
+ <% type_name = calculator.type.demodulize.underscore %>
4
+ <p>
5
+ <%= calculator.description %>
6
+ </p>
7
+ <% if lookup_context.exists?("fields", ["solidus_promotions/admin/calculator_fields/#{type_name}"], true) %>
8
+ <%= render "solidus_promotions/admin/calculator_fields/#{type_name}/fields", calculator: calculator, prefix: param_prefix, form: form %>
9
+ <% else %>
10
+ <%= render "solidus_promotions/admin/calculator_fields/default_fields", calculator: calculator, prefix: param_prefix, form: form %>
11
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <%= fields_for param_prefix, benefit do |form| %>
2
+ <div class="form-group">
3
+ <%= form.label :preferred_variant_id %>
4
+ <%= form.text_field :preferred_variant_id, is: "variant-picker", class: "fullwidth" %>
5
+ </div>
6
+ <div class="form-group">
7
+ <%= form.label :preferred_quantity %>
8
+ <%= form.number_field :preferred_quantity, class: "fullwidth" %>
9
+ </div>
10
+ <div class="form-group">
11
+ <%= form.label :preferred_necessary_quantity %>
12
+ <%= form.number_field :preferred_necessary_quantity, class: "fullwidth" %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <%= render(
17
+ "solidus_promotions/admin/benefit_fields/calculator_fields",
18
+ benefit: benefit,
19
+ param_prefix: param_prefix,
20
+ form: form
21
+ ) %>
@@ -0,0 +1,50 @@
1
+ <div class="card bg-light primary mb-3">
2
+ <div id="<%= dom_id(benefit) %>_header" class="card-header">
3
+ <%= benefit.model_name.human %>
4
+
5
+ <span class="float-right text-dark">
6
+ <% if can?(:destroy, benefit) %>
7
+ <%= link_to_with_icon 'trash', '', solidus_promotions.admin_promotion_benefit_path(@promotion, benefit), method: :delete, class: 'delete' %>
8
+ <% end %>
9
+ </span>
10
+ </div>
11
+ <div class="card-body">
12
+ <div class="row">
13
+ <div class="col-md-6">
14
+ <%= turbo_frame_tag @promotion, dom_id(benefit) do %>
15
+
16
+ <%= render "solidus_promotions/admin/benefits/calculator_select",
17
+ path: solidus_promotions.edit_admin_promotion_benefit_path(@promotion, benefit),
18
+ benefit: benefit %>
19
+
20
+ <%=
21
+ form_with(
22
+ model: benefit,
23
+ scope: :benefit,
24
+ url: solidus_promotions.admin_promotion_benefit_path(@promotion, benefit),
25
+ data: { turbo: false }
26
+ ) do |form| %>
27
+ <%= render 'solidus_promotions/admin/benefits/form', form: form %>
28
+ <div class="row">
29
+ <div class="col-12">
30
+ <%= button_tag t(:update, scope: [:solidus_promotions, :crud]), class: "btn btn-secondary float-right" %>
31
+ </div>
32
+ </div>
33
+ <% end %>
34
+ <% end %>
35
+ </div>
36
+ <div class="col-md-6">
37
+ <div class="form-group">
38
+ <%= label_tag :conditions %>
39
+ <div id="<%= dom_id(benefit) %>_conditions" class="bg-white rounded border p-3">
40
+ <%= render partial: 'solidus_promotions/admin/conditions/condition', collection: benefit.conditions %>
41
+
42
+ <%= turbo_frame_tag benefit, "new_condition" do %>
43
+ <%= link_to t(:add_condition, scope: :solidus_promotions), solidus_promotions.new_admin_promotion_benefit_condition_path(@promotion, benefit), class: 'btn btn-secondary' %>
44
+ <% end %>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
@@ -0,0 +1,16 @@
1
+ <%= form_with model: benefit, scope: :benefit, url: path, method: :get do |form| %>
2
+ <%= form.hidden_field :type %>
3
+ <div class="form-group">
4
+ <%= form.label :calculator_type %>
5
+ <%=
6
+ form.select :calculator_type,
7
+ options_for_benefit_calculator_types(form.object),
8
+ {
9
+ include_blank: t(:choose_benefit_calculator, scope: 'solidus_promotions')
10
+ },
11
+ class: 'custom-select fullwidth',
12
+ onchange: 'this.form.requestSubmit()',
13
+ required: true
14
+ %>
15
+ </div>
16
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= form.hidden_field :type %>
2
+ <%= form.hidden_field :calculator_type %>
3
+ <%= render form.object, benefit: form.object, param_prefix: form.object_name, form: form %>
@@ -0,0 +1,33 @@
1
+ <%= turbo_frame_tag benefit.promotion, "new_benefit" do %>
2
+ <div class="card bg-light mb-3">
3
+ <div class="card-header">
4
+ <%= t(:add_benefit, scope: :solidus_promotions) %>
5
+ </div>
6
+ <div class="card-body">
7
+ <div class="row">
8
+ <div class="col-6">
9
+ <%= render 'solidus_promotions/admin/benefits/type_select', benefit: benefit %>
10
+ <% if benefit.available_calculators.any? %>
11
+ <%= render 'solidus_promotions/admin/benefits/calculator_select', path: solidus_promotions.new_admin_promotion_benefit_path(@promotion), benefit: benefit %>
12
+ <% if benefit.calculator %>
13
+ <%=
14
+ form_with(
15
+ model: benefit,
16
+ scope: :benefit,
17
+ url: solidus_promotions.admin_promotion_benefits_path(@promotion),
18
+ data: { turbo: false }
19
+ ) do |form| %>
20
+ <%= render 'form', form: form %>
21
+ <div class="row">
22
+ <div class="col-12">
23
+ <%= button_tag t(:add, scope: [:solidus_promotions, :crud]), class: "btn btn-secondary float-right" %>
24
+ </div>
25
+ </div>
26
+ <% end %>
27
+ <% end %>
28
+ <% end %>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ <% end %>