solidus_legacy_promotions 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +345 -0
  3. data/Rakefile +43 -0
  4. data/app/assets/config/solidus_legacy_promotions/manifest.js +2 -0
  5. data/app/assets/javascripts/spree/backend/edit_promotion.js +7 -0
  6. data/app/assets/javascripts/spree/backend/promotions/activation.js +26 -0
  7. data/app/assets/javascripts/spree/backend/promotions.js +35 -0
  8. data/app/assets/javascripts/spree/backend/templates/promotions/calculators/fields/tiered_flat_rate.hbs +23 -0
  9. data/app/assets/javascripts/spree/backend/templates/promotions/calculators/fields/tiered_percent.hbs +23 -0
  10. data/app/assets/javascripts/spree/backend/templates/promotions/rules/option_values.hbs +12 -0
  11. data/app/assets/javascripts/spree/backend/views/calculators/tiered.js +54 -0
  12. data/app/assets/javascripts/spree/backend/views/order/details_adjustments.js +43 -0
  13. data/app/assets/javascripts/spree/backend/views/promotions/option_values_rule.js +79 -0
  14. data/app/assets/javascripts/spree/backend/views/promotions.js +3 -0
  15. data/app/assets/stylesheets/solidus_legacy_promotions/promotions/_edit.scss +138 -0
  16. data/app/assets/stylesheets/solidus_legacy_promotions/promotions.scss +3 -0
  17. data/app/assets/stylesheets/spree/backend/sections/_adjustments.scss +3 -0
  18. data/app/decorators/solidus_legacy_promotions/controllers/solidus_admin/solidus_admin_adjustments_controller_decorator.rb +20 -0
  19. data/app/decorators/solidus_legacy_promotions/lib/spree_order_state_machine_decorator.rb +18 -0
  20. data/app/decorators/solidus_legacy_promotions/models/spree_adjustment_decorator.rb +76 -0
  21. data/app/decorators/solidus_legacy_promotions/models/spree_calculator_returns_default_refund_amount_decorator.rb +13 -0
  22. data/app/decorators/solidus_legacy_promotions/models/spree_line_item_decorator.rb +11 -0
  23. data/app/decorators/solidus_legacy_promotions/models/spree_order_decorator.rb +28 -0
  24. data/app/decorators/solidus_legacy_promotions/models/spree_order_updater_decorator.rb +40 -0
  25. data/app/decorators/solidus_legacy_promotions/models/spree_product_decorator.rb +16 -0
  26. data/app/decorators/solidus_legacy_promotions/models/spree_promotion_code_batch_decorator.rb +16 -0
  27. data/app/decorators/solidus_legacy_promotions/models/spree_shipment_decorator.rb +13 -0
  28. data/app/helpers/spree/admin/promotions_helper.rb +15 -0
  29. data/app/helpers/spree/promotion_rules_helper.rb +12 -0
  30. data/app/jobs/spree/promotion_code_batch_job.rb +26 -0
  31. data/app/mailers/spree/promotion_code_batch_mailer.rb +15 -0
  32. data/app/models/spree/calculator/distributed_amount.rb +33 -0
  33. data/app/models/spree/calculator/flat_percent_item_total.rb +23 -0
  34. data/app/models/spree/calculator/flexi_rate.rb +22 -0
  35. data/app/models/spree/calculator/percent_on_line_item.rb +13 -0
  36. data/app/models/spree/calculator/tiered_flat_rate.rb +52 -0
  37. data/app/models/spree/calculator/tiered_percent.rb +62 -0
  38. data/app/models/spree/order_contents.rb +36 -0
  39. data/app/models/spree/order_promotion.rb +27 -0
  40. data/app/models/spree/permission_sets/promotion_display.rb +25 -0
  41. data/app/models/spree/permission_sets/promotion_management.rb +25 -0
  42. data/app/models/spree/promotion/actions/create_adjustment.rb +81 -0
  43. data/app/models/spree/promotion/actions/create_item_adjustments.rb +98 -0
  44. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +139 -0
  45. data/app/models/spree/promotion/actions/free_shipping.rb +59 -0
  46. data/app/models/spree/promotion/order_adjustments_recalculator.rb +92 -0
  47. data/app/models/spree/promotion/rules/first_order.rb +36 -0
  48. data/app/models/spree/promotion/rules/first_repeat_purchase_since.rb +36 -0
  49. data/app/models/spree/promotion/rules/item_total.rb +86 -0
  50. data/app/models/spree/promotion/rules/minimum_quantity.rb +59 -0
  51. data/app/models/spree/promotion/rules/nth_order.rb +45 -0
  52. data/app/models/spree/promotion/rules/one_use_per_user.rb +25 -0
  53. data/app/models/spree/promotion/rules/option_value.rb +50 -0
  54. data/app/models/spree/promotion/rules/product.rb +86 -0
  55. data/app/models/spree/promotion/rules/store.rb +26 -0
  56. data/app/models/spree/promotion/rules/taxon.rb +91 -0
  57. data/app/models/spree/promotion/rules/user.rb +34 -0
  58. data/app/models/spree/promotion/rules/user_logged_in.rb +20 -0
  59. data/app/models/spree/promotion/rules/user_role.rb +45 -0
  60. data/app/models/spree/promotion.rb +271 -0
  61. data/app/models/spree/promotion_action.rb +51 -0
  62. data/app/models/spree/promotion_advertiser.rb +10 -0
  63. data/app/models/spree/promotion_category.rb +8 -0
  64. data/app/models/spree/promotion_chooser.rb +34 -0
  65. data/app/models/spree/promotion_code/batch_builder.rb +68 -0
  66. data/app/models/spree/promotion_code.rb +54 -0
  67. data/app/models/spree/promotion_code_batch.rb +18 -0
  68. data/app/models/spree/promotion_finder.rb +9 -0
  69. data/app/models/spree/promotion_handler/cart.rb +75 -0
  70. data/app/models/spree/promotion_handler/coupon.rb +125 -0
  71. data/app/models/spree/promotion_handler/page.rb +26 -0
  72. data/app/models/spree/promotion_handler/shipping.rb +61 -0
  73. data/app/models/spree/promotion_rule.rb +55 -0
  74. data/app/models/spree/promotion_rule_store.rb +10 -0
  75. data/app/models/spree/promotion_rule_taxon.rb +8 -0
  76. data/app/models/spree/promotion_rule_user.rb +10 -0
  77. data/app/subscribers/spree/order_promotion_subscriber.rb +20 -0
  78. data/app/views/spree/order_mailer/cancel_email.html.erb +45 -0
  79. data/app/views/spree/order_mailer/cancel_email.text.erb +16 -0
  80. data/app/views/spree/order_mailer/confirm_email.html.erb +84 -0
  81. data/app/views/spree/order_mailer/confirm_email.text.erb +38 -0
  82. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
  83. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
  84. data/bin/rails +13 -0
  85. data/config/locales/en.yml +101 -0
  86. data/config/locales/promotion_categories.en.yml +6 -0
  87. data/config/locales/promotions.en.yml +6 -0
  88. data/config/routes.rb +28 -0
  89. data/db/migrate/20160101010001_solidus_one_four_promotions.rb +126 -0
  90. data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +48 -0
  91. data/db/migrate/20180202190713_create_promotion_rule_stores.rb +14 -0
  92. data/db/migrate/20180328172631_add_join_characters_to_promotion_code_batch.rb +15 -0
  93. data/db/migrate/20190106184413_remove_code_from_spree_promotions.rb +46 -0
  94. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  95. data/db/migrate/20230322085416_remove_match_policy_from_spree_promotion.rb +7 -0
  96. data/db/migrate/20230325132905_remove_unused_columns_from_promotion_rules.rb +10 -0
  97. data/db/migrate/20231027084517_add_order_promotions_foreign_key.rb +14 -0
  98. data/db/migrate/20240621100123_add_promotion_code_id_to_spree_adjustments.rb +10 -0
  99. data/db/migrate/20240622113334_move_adjustment_eligible_to_legacy_promotions.rb +11 -0
  100. data/lib/components/admin/solidus_admin/orders/show/adjustments/index/source/spree_promotion_action/component.rb +17 -0
  101. data/lib/components/admin/solidus_admin/promotion_categories/index/component.rb +56 -0
  102. data/lib/components/admin/solidus_admin/promotions/index/component.rb +104 -0
  103. data/lib/components/admin/solidus_admin/promotions/index/component.yml +10 -0
  104. data/lib/components/admin/solidus_legacy_promotions/orders/index/component.rb +15 -0
  105. data/lib/components/admin/solidus_legacy_promotions/orders/index/component.yml +20 -0
  106. data/lib/controllers/admin/solidus_admin/promotion_categories_controller.rb +29 -0
  107. data/lib/controllers/admin/solidus_admin/promotions_controller.rb +46 -0
  108. data/lib/controllers/backend/spree/admin/promotion_actions_controller.rb +51 -0
  109. data/lib/controllers/backend/spree/admin/promotion_categories_controller.rb +8 -0
  110. data/lib/controllers/backend/spree/admin/promotion_code_batches_controller.rb +30 -0
  111. data/lib/controllers/backend/spree/admin/promotion_codes_controller.rb +48 -0
  112. data/lib/controllers/backend/spree/admin/promotion_rules_controller.rb +60 -0
  113. data/lib/controllers/backend/spree/admin/promotions_controller.rb +66 -0
  114. data/lib/solidus_legacy_promotions/configuration.rb +115 -0
  115. data/lib/solidus_legacy_promotions/engine.rb +97 -0
  116. data/lib/solidus_legacy_promotions/migrations/promotions_with_code_handlers.rb +68 -0
  117. data/lib/solidus_legacy_promotions/testing_support/factories/calculator_factory.rb +7 -0
  118. data/lib/solidus_legacy_promotions/testing_support/factories/order_factory.rb +22 -0
  119. data/lib/solidus_legacy_promotions/testing_support/factories/order_promotion_factory.rb +8 -0
  120. data/lib/solidus_legacy_promotions/testing_support/factories/promotion_category_factory.rb +7 -0
  121. data/lib/solidus_legacy_promotions/testing_support/factories/promotion_code_factory.rb +8 -0
  122. data/lib/solidus_legacy_promotions/testing_support/factories/promotion_factory.rb +98 -0
  123. data/lib/solidus_legacy_promotions/testing_support/factory_bot.rb +28 -0
  124. data/lib/solidus_legacy_promotions.rb +28 -0
  125. data/lib/tasks/solidus_legacy_promotions/delete_ineligible_adjustments.rake +8 -0
  126. data/lib/views/backend/spree/admin/adjustments/_adjustment.html.erb +24 -0
  127. data/lib/views/backend/spree/admin/orders/_adjustments.html.erb +19 -0
  128. data/lib/views/backend/spree/admin/orders/_order_details.html.erb +32 -0
  129. data/lib/views/backend/spree/admin/orders/confirm.html.erb +59 -0
  130. data/lib/views/backend/spree/admin/promotion_actions/create.js.erb +10 -0
  131. data/lib/views/backend/spree/admin/promotion_actions/destroy.js.erb +1 -0
  132. data/lib/views/backend/spree/admin/promotion_categories/_form.html.erb +14 -0
  133. data/lib/views/backend/spree/admin/promotion_categories/edit.html.erb +10 -0
  134. data/lib/views/backend/spree/admin/promotion_categories/index.html.erb +47 -0
  135. data/lib/views/backend/spree/admin/promotion_categories/new.html.erb +10 -0
  136. data/lib/views/backend/spree/admin/promotion_code_batches/_form_fields.html.erb +22 -0
  137. data/lib/views/backend/spree/admin/promotion_code_batches/download.csv.ruby +8 -0
  138. data/lib/views/backend/spree/admin/promotion_code_batches/index.html.erb +65 -0
  139. data/lib/views/backend/spree/admin/promotion_code_batches/new.html.erb +8 -0
  140. data/lib/views/backend/spree/admin/promotion_codes/index.csv.ruby +8 -0
  141. data/lib/views/backend/spree/admin/promotion_codes/index.html.erb +32 -0
  142. data/lib/views/backend/spree/admin/promotion_codes/new.html.erb +31 -0
  143. data/lib/views/backend/spree/admin/promotion_rules/create.js.erb +8 -0
  144. data/lib/views/backend/spree/admin/promotion_rules/destroy.js.erb +3 -0
  145. data/lib/views/backend/spree/admin/promotions/_actions.html.erb +37 -0
  146. data/lib/views/backend/spree/admin/promotions/_activations_edit.html.erb +22 -0
  147. data/lib/views/backend/spree/admin/promotions/_activations_new.html.erb +43 -0
  148. data/lib/views/backend/spree/admin/promotions/_form.html.erb +67 -0
  149. data/lib/views/backend/spree/admin/promotions/_promotion_action.html.erb +13 -0
  150. data/lib/views/backend/spree/admin/promotions/_promotion_rule.html.erb +12 -0
  151. data/lib/views/backend/spree/admin/promotions/_rules.html.erb +42 -0
  152. data/lib/views/backend/spree/admin/promotions/actions/_create_adjustment.html.erb +2 -0
  153. data/lib/views/backend/spree/admin/promotions/actions/_create_item_adjustments.html.erb +6 -0
  154. data/lib/views/backend/spree/admin/promotions/actions/_create_quantity_adjustments.html.erb +10 -0
  155. data/lib/views/backend/spree/admin/promotions/actions/_free_shipping.html.erb +0 -0
  156. data/lib/views/backend/spree/admin/promotions/actions/_promotion_calculators_with_custom_fields.html.erb +29 -0
  157. data/lib/views/backend/spree/admin/promotions/calculators/_default_fields.html.erb +6 -0
  158. data/lib/views/backend/spree/admin/promotions/calculators/distributed_amount/_fields.html.erb +56 -0
  159. data/lib/views/backend/spree/admin/promotions/calculators/flat_rate/_fields.html.erb +6 -0
  160. data/lib/views/backend/spree/admin/promotions/calculators/tiered_flat_rate/_fields.html.erb +30 -0
  161. data/lib/views/backend/spree/admin/promotions/calculators/tiered_percent/_fields.html.erb +30 -0
  162. data/lib/views/backend/spree/admin/promotions/edit.html.erb +40 -0
  163. data/lib/views/backend/spree/admin/promotions/index.html.erb +124 -0
  164. data/lib/views/backend/spree/admin/promotions/new.html.erb +14 -0
  165. data/lib/views/backend/spree/admin/promotions/rules/_first_order.html.erb +0 -0
  166. data/lib/views/backend/spree/admin/promotions/rules/_first_repeat_purchase_since.html.erb +13 -0
  167. data/lib/views/backend/spree/admin/promotions/rules/_item_total.html.erb +14 -0
  168. data/lib/views/backend/spree/admin/promotions/rules/_minimum_quantity.html.erb +5 -0
  169. data/lib/views/backend/spree/admin/promotions/rules/_nth_order.html.erb +12 -0
  170. data/lib/views/backend/spree/admin/promotions/rules/_one_use_per_user.html.erb +0 -0
  171. data/lib/views/backend/spree/admin/promotions/rules/_option_value.html.erb +13 -0
  172. data/lib/views/backend/spree/admin/promotions/rules/_product.html.erb +15 -0
  173. data/lib/views/backend/spree/admin/promotions/rules/_store.html.erb +6 -0
  174. data/lib/views/backend/spree/admin/promotions/rules/_taxon.html.erb +9 -0
  175. data/lib/views/backend/spree/admin/promotions/rules/_user.html.erb +4 -0
  176. data/lib/views/backend/spree/admin/promotions/rules/_user_logged_in.html.erb +0 -0
  177. data/lib/views/backend/spree/admin/promotions/rules/_user_role.html.erb +12 -0
  178. data/solidus_legacy_promotions.gemspec +29 -0
  179. metadata +262 -0
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :promotion, class: 'Spree::Promotion' do
5
+ name { 'Promo' }
6
+
7
+ transient do
8
+ code { nil }
9
+ end
10
+ before(:create) do |promotion, evaluator|
11
+ if evaluator.code
12
+ promotion.codes << build(:promotion_code, promotion:, value: evaluator.code)
13
+ end
14
+ end
15
+
16
+ trait :with_action do
17
+ transient do
18
+ promotion_action_class { Spree::Promotion::Actions::CreateAdjustment }
19
+ end
20
+
21
+ after(:create) do |promotion, evaluator|
22
+ promotion.actions << evaluator.promotion_action_class.new
23
+ end
24
+ end
25
+
26
+ trait :with_adjustable_action do
27
+ transient do
28
+ preferred_amount { 10 }
29
+ calculator_class { Spree::Calculator::FlatRate }
30
+ promotion_action_class { Spree::Promotion::Actions::CreateItemAdjustments }
31
+ end
32
+
33
+ after(:create) do |promotion, evaluator|
34
+ calculator = evaluator.calculator_class.new
35
+ calculator.preferred_amount = evaluator.preferred_amount
36
+ evaluator.promotion_action_class.create!(calculator:, promotion:)
37
+ end
38
+ end
39
+
40
+ factory :promotion_with_action_adjustment, traits: [:with_adjustable_action]
41
+
42
+ trait :with_line_item_adjustment do
43
+ transient do
44
+ adjustment_rate { 10 }
45
+ end
46
+
47
+ with_adjustable_action
48
+ preferred_amount { adjustment_rate }
49
+ end
50
+
51
+ factory :promotion_with_item_adjustment, traits: [:with_line_item_adjustment]
52
+
53
+ trait :with_free_shipping do
54
+ after(:create) do |promotion|
55
+ Spree::Promotion::Actions::FreeShipping.create!(promotion:)
56
+ end
57
+ end
58
+
59
+ trait :with_order_adjustment do
60
+ transient do
61
+ weighted_order_adjustment_amount { 10 }
62
+ end
63
+
64
+ with_adjustable_action
65
+ preferred_amount { weighted_order_adjustment_amount }
66
+ promotion_action_class { Spree::Promotion::Actions::CreateAdjustment }
67
+ end
68
+
69
+ factory :promotion_with_order_adjustment, traits: [:with_order_adjustment]
70
+
71
+ trait :with_item_total_rule do
72
+ transient do
73
+ item_total_threshold_amount { 10 }
74
+ end
75
+
76
+ after(:create) do |promotion, evaluator|
77
+ rule = Spree::Promotion::Rules::ItemTotal.create!(
78
+ promotion:,
79
+ preferred_operator: 'gte',
80
+ preferred_amount: evaluator.item_total_threshold_amount
81
+ )
82
+ promotion.rules << rule
83
+ promotion.save!
84
+ end
85
+ end
86
+ factory :promotion_with_item_total_rule, traits: [:with_item_total_rule]
87
+ trait :with_first_order_rule do
88
+ after(:create) do |promotion, _evaluator|
89
+ rule = Spree::Promotion::Rules::FirstOrder.create!(
90
+ promotion:,
91
+ )
92
+ promotion.rules << rule
93
+ promotion.save!
94
+ end
95
+ end
96
+ factory :promotion_with_first_order_rule, traits: [:with_first_order_rule]
97
+ end
98
+ end
@@ -0,0 +1,28 @@
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 SolidusLegacyPromotions
10
+ module TestingSupport
11
+ module FactoryBot
12
+ FACTORIES = Dir["#{::SolidusLegacyPromotions::Engine.root}/lib/solidus_legacy_promotions/testing_support/factories/**/*_factory.rb"].sort
13
+
14
+ def self.definition_file_paths
15
+ @paths ||= FACTORIES.map { |path| path.sub(/.rb\z/, '') }
16
+ end
17
+
18
+ def self.add_definitions!
19
+ ::FactoryBot.definition_file_paths.unshift(*definition_file_paths).uniq!
20
+ end
21
+
22
+ def self.add_paths_and_load!
23
+ add_definitions!
24
+ ::FactoryBot.reload
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "solidus_core"
4
+ require "solidus_api"
5
+ require "solidus_support"
6
+
7
+ # We carry controllers and views for both the traditional backend
8
+ # and the new Solidus Admin interface, but we want to continue to function
9
+ # if either of them are not present. If they are present,
10
+ # however, they need to load before us.
11
+ begin
12
+ require 'solidus_admin'
13
+ rescue LoadError
14
+ # Solidus Admin is not available
15
+ end
16
+
17
+ begin
18
+ require "solidus_backend"
19
+ rescue LoadError
20
+ # Solidus backend is not available
21
+ end
22
+
23
+ module SolidusLegacyPromotions
24
+ VERSION = Spree.solidus_version
25
+ end
26
+
27
+ require "solidus_legacy_promotions/configuration"
28
+ require "solidus_legacy_promotions/engine"
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :solidus_legacy_promotions do
4
+ desc "Delete ineligible adjustments"
5
+ task delete_ineligible_adjustments: :environment do
6
+ Spree::Adjustment.where(eligible: false).delete_all
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ <%
2
+ @edit_url = edit_admin_order_adjustment_path(@order, adjustment)
3
+ @delete_url = admin_order_adjustment_path(@order, adjustment)
4
+ %>
5
+ <tr id="<%= spree_dom_id(adjustment) %>"
6
+ data-hook="adjustment_row"
7
+ class="<%= "adjustment-ineligible" if !adjustment.eligible? %>"
8
+ >
9
+ <td><%= display_adjustable(adjustment.adjustable) %></td>
10
+ <td><%= adjustment.label %></td>
11
+ <td><%= adjustment.display_amount.to_html %></td>
12
+ <td><%= adjustment_state(adjustment) %></td>
13
+ <td class='actions'>
14
+ <% unless adjustment.finalized? %>
15
+ <% if can?(:update, adjustment) %>
16
+ <%= link_to_edit adjustment, no_text: true %>
17
+ <% end %>
18
+
19
+ <% if can?(:destroy, adjustment) %>
20
+ <%= link_to_delete adjustment, no_text: true %>
21
+ <% end %>
22
+ <% end %>
23
+ </td>
24
+ </tr>
@@ -0,0 +1,19 @@
1
+ <fieldset class="no-border-bottom">
2
+ <legend><%= title %></legend>
3
+ <table>
4
+ <thead>
5
+ <tr>
6
+ <th><%= Spree::Adjustment.human_attribute_name(:name) %></th>
7
+ <th><%= Spree::Adjustment.human_attribute_name(:amount) %></th>
8
+ </tr>
9
+ </thead>
10
+ <tbody data-hook="order_details_adjustments">
11
+ <% adjustments.eligible.group_by(&:label).each do |label, adjustments| %>
12
+ <tr class="total">
13
+ <td><%= label %>:</td>
14
+ <td class="total"><span><%= Spree::Money.new(adjustments.sum(&:amount), currency: adjustments.first.order.try(:currency)) %></span></td>
15
+ </tr>
16
+ <% end %>
17
+ </tbody>
18
+ </table>
19
+ </fieldset>
@@ -0,0 +1,32 @@
1
+ <div class="js-order-line-item-adjustments <%= "hidden" if order.line_item_adjustments.eligible.none? %>">
2
+ <%=
3
+ render "spree/admin/orders/adjustments", {
4
+ adjustments: order.line_item_adjustments,
5
+ order: order,
6
+ title: t('spree.line_item_adjustments')
7
+ }
8
+ %>
9
+ </div>
10
+ <div class="js-order-shipment-adjustments <%= "hidden" if order.shipment_adjustments.eligible.none? %>">
11
+ <%=
12
+ render "spree/admin/orders/adjustments", {
13
+ adjustments: order.shipment_adjustments,
14
+ order: order,
15
+ title: t('spree.shipment_adjustments')
16
+ }
17
+ %>
18
+ </div>
19
+ <div class="js-order-adjustments <%= "hidden" if order.adjustments.eligible.none? %>">
20
+ <%=
21
+ render "spree/admin/orders/adjustments", {
22
+ adjustments: order.adjustments,
23
+ order: order,
24
+ title: t('spree.order_adjustments')
25
+ }
26
+ %>
27
+ </div>
28
+
29
+ <fieldset class="no-border-bottom <%= "hidden" if order.line_items.none? %>" id="order-total" data-hook="order_details_total">
30
+ <legend><%= t('spree.order_total') %></legend>
31
+ <span class="order-total"><%= order.display_total %></span>
32
+ </fieldset>
@@ -0,0 +1,59 @@
1
+ <%= render partial: 'spree/admin/shared/order_tabs', locals: {current: 'Confirm'} %>
2
+
3
+ <% admin_breadcrumb(t('spree.confirm_order')) %>
4
+
5
+ <%= render partial: 'spree/admin/orders/confirm/customer_details', locals: {order: @order} %>
6
+
7
+ <% if Spree::Order.checkout_step_names.include?(:delivery) %>
8
+ <%= render partial: 'spree/admin/orders/confirm/shipment', collection: @order.shipments, locals: {order: @order} %>
9
+ <% else %>
10
+ <%= render partial: 'spree/admin/orders/confirm/line_items', locals: {order: @order} %>
11
+ <% end %>
12
+
13
+ <%=
14
+ render(
15
+ partial: 'spree/admin/orders/adjustments',
16
+ locals: {
17
+ adjustments: @order.line_item_adjustments,
18
+ order: @order,
19
+ title: t('spree.line_item_adjustments'),
20
+ }
21
+ ) if @order.line_item_adjustments.eligible.any?
22
+ %>
23
+
24
+ <%=
25
+ render(
26
+ partial: 'spree/admin/orders/adjustments',
27
+ locals: {
28
+ adjustments: @order.shipment_adjustments,
29
+ order: @order,
30
+ title: t('spree.shipment_adjustments'),
31
+ }
32
+ ) if @order.shipment_adjustments.eligible.any?
33
+ %>
34
+
35
+ <%=
36
+ render(
37
+ partial: 'spree/admin/orders/adjustments',
38
+ locals: {
39
+ adjustments: @order.adjustments,
40
+ order: @order,
41
+ title: t('spree.order_adjustments'),
42
+ }
43
+ ) if @order.adjustments.eligible.any?
44
+ %>
45
+
46
+ <% if @order.line_items.exists? %>
47
+ <fieldset class="no-border-bottom" id="order-total" data-hook="order_details_total">
48
+ <legend><%= t('spree.order_total') %></legend>
49
+ <span class="order-total"><%= @order.display_total %></span>
50
+ </fieldset>
51
+ <% end %>
52
+
53
+ <%= render partial: 'spree/admin/orders/confirm/payments', locals: {payments: @order.payments} %>
54
+
55
+ <div class="form-buttons filter-actions actions" data-hook="complete-order-button">
56
+ <%= button_to [:complete, :admin, @order], { class: 'button', method: 'put' } do %>
57
+ <%= t('spree.complete_order') %>
58
+ <% end %>
59
+ </div>
@@ -0,0 +1,10 @@
1
+ $('#actions').append('<%= escape_javascript( render(partial: 'spree/admin/promotions/promotion_action', object: @promotion_action) ) %>');
2
+ $('#actions .no-objects-found').hide();
3
+ $(".variant_autocomplete").variantAutocomplete();
4
+
5
+ initPromotionActions();
6
+
7
+
8
+ $('#<%= dom_id @promotion_action %>').hide();
9
+ $('#<%= dom_id @promotion_action %>').fadeIn();
10
+ new Spree.CalculatorEditView({el: $('#<%= dom_id @promotion_action %> .js-calculator-fields')});
@@ -0,0 +1 @@
1
+ $('#<%= dom_id @promotion_action %>').fadeOut().remove();
@@ -0,0 +1,14 @@
1
+ <%= render partial: 'spree/shared/error_messages', locals: { target: @promotion_category } %>
2
+
3
+ <div class='row'>
4
+ <div class='col-4'>
5
+ <%= f.field_container :name do %>
6
+ <%= f.label :name %>
7
+ <%= f.text_field :name, class: 'fullwidth' %>
8
+ <% end %>
9
+ <%= f.field_container :code do %>
10
+ <%= f.label :code %>
11
+ <%= f.text_field :code, class: 'fullwidth' %>
12
+ <% end %>
13
+ </div>
14
+ </div>
@@ -0,0 +1,10 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path) %>
2
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::PromotionCategory), spree.admin_promotion_categories_path) %>
3
+ <% admin_breadcrumb(@promotion_category.name) %>
4
+
5
+ <%= form_for @promotion_category, url: object_url, method: :put do |f| %>
6
+ <fieldset class="no-border-top">
7
+ <%= render partial: 'form', locals: { f: f } %>
8
+ <%= render partial: 'spree/admin/shared/edit_resource_links' %>
9
+ </fieldset>
10
+ <% end %>
@@ -0,0 +1,47 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path) %>
2
+ <% admin_breadcrumb(plural_resource_name(Spree::PromotionCategory)) %>
3
+
4
+ <% content_for :page_actions do %>
5
+ <% if can?(:create, Spree::PromotionCategory) %>
6
+ <li>
7
+ <%= link_to t('spree.new_promotion_category'), spree.new_admin_promotion_category_path, class: 'btn btn-primary' %>
8
+ </li>
9
+ <% end %>
10
+ <% end %>
11
+
12
+ <% if @promotion_categories.any? %>
13
+ <table class="index">
14
+ <colgroup>
15
+ <col style="width: 40%">
16
+ <col style="width: 40%">
17
+ <col style="width: 20%">
18
+ </colgroup>
19
+ <thead>
20
+ <th><%= Spree::PromotionCategory.human_attribute_name :name %></th>
21
+ <th><%= Spree::PromotionCategory.human_attribute_name :code %></th>
22
+ <th class='actions'></th>
23
+ </thead>
24
+ <tbody>
25
+ <% @promotion_categories.each do |promotion_category| %>
26
+ <tr>
27
+ <td><%= promotion_category.name %></td>
28
+ <td><%= promotion_category.code %></td>
29
+ <td class="actions">
30
+ <% if can?(:update, promotion_category) %>
31
+ <%= link_to_edit promotion_category, no_text: true %>
32
+ <% end %>
33
+ <% if can?(:destroy, promotion_category) %>
34
+ <%= link_to_delete promotion_category, no_text: true %>
35
+ <% end %>
36
+ </td>
37
+ </tr>
38
+ <% end %>
39
+ </tbody>
40
+ </table>
41
+ <% else %>
42
+ <div class="no-objects-found">
43
+ <%= render 'spree/admin/shared/no_objects_found',
44
+ resource: Spree::PromotionCategory,
45
+ new_resource_url: new_object_url %>
46
+ </div>
47
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path) %>
2
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::PromotionCategory), spree.admin_promotion_categories_path) %>
3
+ <% admin_breadcrumb(t('spree.new_promotion_category')) %>
4
+
5
+ <%= form_for :promotion_category, url: collection_url do |f| %>
6
+ <fieldset class="no-border-top">
7
+ <%= render partial: 'form', locals: { f: f } %>
8
+ <%= render partial: 'spree/admin/shared/new_resource_links' %>
9
+ </fieldset>
10
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <div class="field">
2
+ <%= batch.label :base_code, class: "required" %>
3
+ <%= batch.text_field :base_code, class: "fullwidth", required: true %>
4
+ </div>
5
+ <div class="field">
6
+ <%= batch.label :number_of_codes, class: "required" %>
7
+ <%= batch.number_field :number_of_codes, class: "fullwidth", min: 1, required: true %>
8
+ </div>
9
+ <div class="field">
10
+ <%= batch.label :join_characters %>
11
+ <%= batch.text_field :join_characters, class: "fullwidth" %>
12
+ </div>
13
+ <% unless promotion_id %>
14
+ <div class="field">
15
+ <%= f.label :per_code_usage_limit %>
16
+ <%= f.text_field :per_code_usage_limit, class: "fullwidth" %>
17
+ </div>
18
+ <% end %>
19
+ <div class="field">
20
+ <%= batch.label :email %>
21
+ <%= batch.text_field :email, class: "fullwidth" %>
22
+ </div>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ CSV.generate do |csv|
4
+ csv << ['Code']
5
+ @promotion_code_batch.promotion_codes.order(:id).pluck(:value).each do |value|
6
+ csv << [value]
7
+ end
8
+ end
@@ -0,0 +1,65 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path) %>
2
+ <% admin_breadcrumb(link_to @promotion.name, spree.edit_admin_promotion_path(@promotion.id)) %>
3
+ <% admin_breadcrumb(plural_resource_name(Spree::PromotionCodeBatch)) %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li>
7
+ <% if can?(:create, Spree::PromotionCodeBatch) %>
8
+ <%= link_to t('spree.new_promotion_code_batch'), new_object_url, class: 'btn btn-primary' %>
9
+ <% end %>
10
+ </li>
11
+ <% end %>
12
+
13
+ <% if @promotion_code_batches.any? %>
14
+ <table>
15
+ <thead>
16
+ <tr>
17
+ <th><%= Spree::PromotionCodeBatch.human_attribute_name(:base_code) %></th>
18
+ <th><%= Spree::PromotionCodeBatch.human_attribute_name(:total_codes) %></th>
19
+ <th><%= Spree::PromotionCodeBatch.human_attribute_name(:status) %></th>
20
+ <th><%= Spree::PromotionCodeBatch.human_attribute_name(:email) %></th>
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ <% @promotion_code_batches.each do |promotion_code_batch| %>
25
+ <tr>
26
+ <td><%= promotion_code_batch.base_code %></td>
27
+ <td><%= promotion_code_batch.number_of_codes %></td>
28
+ <td>
29
+ <% if promotion_code_batch.error.present? %>
30
+ <%= t(
31
+ "spree.promotion_code_batches.errored",
32
+ error: promotion_code_batch.error
33
+ ) %>
34
+ <% elsif promotion_code_batch.finished? %>
35
+ <%= t(
36
+ "spree.promotion_code_batches.finished",
37
+ number_of_codes: promotion_code_batch.number_of_codes
38
+ ) %>
39
+ <%= link_to(
40
+ t('spree.download_promotion_codes_list'),
41
+ admin_promotion_promotion_code_batch_download_path(
42
+ promotion_code_batch_id: promotion_code_batch.id,
43
+ format: :csv
44
+ )
45
+ ) %>
46
+ <% else %>
47
+ <%= t(
48
+ "spree.promotion_code_batches.processing",
49
+ number_of_codes: promotion_code_batch.number_of_codes,
50
+ number_of_codes_processed: promotion_code_batch.promotion_codes.count
51
+ ) %>
52
+ <% end %>
53
+ </td>
54
+ <td><%= promotion_code_batch.email %></td>
55
+ </tr>
56
+ <% end %>
57
+ </tbody>
58
+ </table>
59
+ <% else %>
60
+ <div class="no-objects-found">
61
+ <%= render 'spree/admin/shared/no_objects_found',
62
+ resource: Spree::PromotionCodeBatch,
63
+ new_resource_url: new_object_url %>
64
+ </div>
65
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path) %>
2
+ <% admin_breadcrumb(link_to @promotion.name, spree.admin_promotion_path(@promotion.id)) %>
3
+ <% admin_breadcrumb(plural_resource_name(Spree::PromotionCodeBatch)) %>
4
+ <%= form_for :promotion_code_batch, url: collection_url do |batch| %>
5
+ <%= batch.hidden_field :promotion_id, value: params[:promotion_id] %>
6
+ <%= render partial: 'form_fields', locals: {batch: batch, promotion_id: params[:promotion_id]} %>
7
+ <%= batch.submit t('spree.actions.create'), class: 'btn btn-primary' %>
8
+ <% end %>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ CSV.generate do |csv|
4
+ csv << ['Code']
5
+ @promotion_codes.order(:id).pluck(:value).each do |value|
6
+ csv << [value]
7
+ end
8
+ end
@@ -0,0 +1,32 @@
1
+ <% admin_breadcrumb link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path %>
2
+ <% admin_breadcrumb link_to(@promotion.name, spree.edit_admin_promotion_path(@promotion)) %>
3
+ <% admin_breadcrumb plural_resource_name(Spree::PromotionCode) %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li>
7
+ <% if can?(:create, Spree::PromotionCode) && !@promotion.apply_automatically? %>
8
+ <%= link_to t('spree.create_promotion_code'), new_admin_promotion_promotion_code_path(promotion_id: @promotion.id), class: 'btn btn-primary' %>
9
+ <% end %>
10
+
11
+ <%= link_to t('spree.download_promotion_codes_list'), admin_promotion_promotion_codes_path(promotion_id: @promotion.id, format: :csv), class: 'btn btn-primary' %>
12
+ </li>
13
+ <% end %>
14
+
15
+ <div class="pagination-summary">
16
+ <%= page_entries_info(@promotion_codes) %>
17
+ </div>
18
+
19
+ <table>
20
+ <thead>
21
+ <th><%= Spree::PromotionCode.human_attribute_name :value %></th>
22
+ </thead>
23
+ <tbody>
24
+ <% @promotion_codes.each do |promotion_code| %>
25
+ <tr>
26
+ <td><%= promotion_code.value %></td>
27
+ </tr>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
31
+
32
+ <%= paginate @promotion_codes, theme: "solidus_admin" %>
@@ -0,0 +1,31 @@
1
+ <% admin_breadcrumb link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path %>
2
+ <% admin_breadcrumb link_to(@promotion.name, spree.edit_admin_promotion_path(@promotion)) %>
3
+ <% admin_breadcrumb plural_resource_name(Spree::PromotionCode) %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li>
7
+ <%= link_to t('spree.view_promotion_codes_list'), admin_promotion_promotion_codes_path(promotion_id: @promotion.id), class: 'btn btn-primary' %>
8
+
9
+ <%= link_to t('spree.download_promotion_codes_list'), admin_promotion_promotion_codes_path(promotion_id: @promotion.id, format: :csv), class: 'btn btn-primary' %>
10
+ </li>
11
+ <% end %>
12
+
13
+ <%= form_for [:admin, @promotion, @promotion_code], method: :post do |f| %>
14
+ <fieldset class="no-border-top">
15
+ <%= render partial: 'spree/shared/error_messages', locals: { target: @promotion_code } %>
16
+
17
+ <div class="row">
18
+ <div class="col-4">
19
+ <%= f.field_container :value do %>
20
+ <%= f.label :value, class: 'required' %>
21
+ <%= f.text_field :value, class: 'fullwidth', required: true %>
22
+ <% end %>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="form-buttons filter-actions actions" data-hook="buttons">
27
+ <%= f.submit t('spree.actions.create'), class: 'btn btn-primary' %>
28
+ <%= link_to t('spree.actions.cancel'), admin_promotion_promotion_codes_url(@promotion), class: 'button' %>
29
+ </div>
30
+ </fieldset>
31
+ <% end %>
@@ -0,0 +1,8 @@
1
+ $('#rules').append('<%= escape_javascript( render(partial: 'spree/admin/promotions/promotion_rule', object: @promotion_rule) ) %>');
2
+ $('#rules .no-objects-found').hide();
3
+
4
+ $('.product_picker').productAutocomplete();
5
+ $('.user_picker').userAutocomplete();
6
+ $('.taxon_picker').taxonAutocomplete();
7
+
8
+ $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
@@ -0,0 +1,3 @@
1
+ $('#<%= dom_id @promotion_rule %>').fadeOut().remove();
2
+
3
+ $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
@@ -0,0 +1,37 @@
1
+ <fieldset id="action_fields" class="no-border-top">
2
+
3
+ <%= form_tag spree.admin_promotion_promotion_actions_path(@promotion), remote: true, id: 'new_promotion_action_form' do %>
4
+ <% options = options_for_select(Spree::Config.promotions.actions.map {|action| [ action.model_name.human, action.name] } ) %>
5
+ <fieldset>
6
+ <legend align="center"><%= t('spree.promotion_actions') %></legend>
7
+ <% if can?(:update, @promotion) %>
8
+ <div class="field">
9
+ <%= label_tag :action_type, t('spree.adjustment_type') %>
10
+ <%= admin_hint t('spree.adjustment_type'), t(:promotions, scope: [:spree, :hints, "spree/calculator"]) %>
11
+ <%= select_tag 'action_type', options, include_blank: t(:choose_promotion_action, scope: 'spree'), class: 'custom-select fullwidth', required: true %>
12
+ </div>
13
+ <div class="filter-actions actions">
14
+ <%= button_tag t('spree.actions.add'), class: 'btn btn-primary' %>
15
+ </div>
16
+ <% end %>
17
+ </fieldset>
18
+ <% end %>
19
+
20
+ <%= form_for @promotion, url: spree.admin_promotion_path(@promotion), method: :put do |f| %>
21
+ <div id="actions" class="filter_list">
22
+ <% if @promotion.actions.any? %>
23
+ <%= render partial: 'promotion_action', collection: @promotion.actions %>
24
+ <% else %>
25
+ <div class="no-objects-found">
26
+ <%= t('spree.no_actions_added') %>
27
+ </div>
28
+ <% end %>
29
+ </div>
30
+ <% if can?(:update, @promotion) %>
31
+ <div class="filter-actions actions promotion-update">
32
+ <%= button_tag t('spree.actions.update'), class: 'btn btn-primary' %>
33
+ </div>
34
+ <% end %>
35
+ <% end %>
36
+
37
+ </fieldset>