diff --git a/app/controllers/spree/admin/promotion_batches_controller.rb b/app/controllers/spree/admin/promotion_batches_controller.rb
index d60e3e83b5..6f3ceec1dc 100644
--- a/app/controllers/spree/admin/promotion_batches_controller.rb
+++ b/app/controllers/spree/admin/promotion_batches_controller.rb
@@ -1,62 +1,46 @@
module Spree
module Admin
class PromotionBatchesController < ResourceController
- def update
- if @object.template_promotion_id
- flash[:error] = Spree.t(:template_promotion_already_assigned)
- respond_with(@object) do |format|
- format.html { render action: :edit, status: :unprocessable_entity }
- format.js { render layout: false, status: :unprocessable_entity }
- end
- return
- end
- super
- end
-
- def destroy
- result = Spree::PromotionBatches::Destroy.call(promotion_batch: @promotion_batch)
-
- if result.success?
- flash[:success] = flash_message_for(@promotion_batch, :successfully_removed)
- else
- flash[:error] = @promotion_batch.errors.full_messages.join(', ')
- end
-
- respond_with(@promotion_batch) do |format|
- format.html { redirect_to location_after_destroy }
- format.js { render_js_for_destroy }
- end
- end
-
- def csv_export
- send_data Spree::PromotionBatches::PromotionCodesExporter.new(params).call,
- filename: "promo_codes_from_batch_id_#{params[:id]}.csv",
- disposition: :attachment,
- type: 'text/csv'
- end
-
- def csv_import
- file = params[:file]
- Spree::PromotionBatches::PromotionCodesImporter.new(file: file, promotion_batch_id: params[:id]).call
- redirect_back fallback_location: admin_promotions_path, notice: Spree.t('code_upload')
- rescue Spree::PromotionBatches::PromotionCodesImporter::Error => e
- redirect_back fallback_location: admin_promotions_path, alert: e.message
- end
-
- def populate
- batch_id = params[:id]
- options = {
- batch_size: params[:batch_size].to_i,
- affix: params.dig(:code, :affix)&.to_sym,
- content: params[:affix_content],
- deny_list: params[:forbidden_phrases].split,
- random_part_bytes: params[:random_part_bytes].to_i
- }
-
- Spree::Promotions::PopulatePromotionBatch.new(batch_id, options).call
-
- flash[:success] = Spree.t('promotion_batch_populated')
- redirect_to spree.edit_admin_promotion_batch_url(@promotion_batch)
+ before_action :set_template_promotion
+
+ def index
+ @promotion_batches = Spree::PromotionBatch.where(template_promotion: @template_promotion)
+ end
+
+ def new
+ @promotion_batch = @template_promotion.promotion_batches.build
+ end
+
+ def create
+ Spree::PromotionBatches::CreateWithRandomCodes.new.call(template_promotion: @template_promotion, amount: params[:amount].to_i, random_characters: params[:random_characters].to_i, prefix: params[:prefix], suffix: params[:suffix])
+ end
+
+ def import; end
+
+ def process_import
+ file = params[:file].read
+ Spree::PromotionBatches::CreateWithCodes.new.call(template_promotion: @template_promotion, codes: file.split("\n"))
+ redirect_to(admin_template_promotion_promotion_batches_path(template_promotion_id: @template_promotion.id))
+ end
+
+ def export
+ @promotion_batch = @template_promotion.promotion_batches.find(params[:promotion_batch_id])
+ csv = Spree::PromotionBatches::Export.new.call(promotion_batch: @promotion_batch)
+ send_data csv, filename: "codes_#{@promotion_batch}.csv"
+ end
+
+ private
+
+ def collection_url
+ admin_template_promotion_promotion_batches_url(@template_promotion)
+ end
+
+ def new_object_url(options = nil)
+ new_admin_template_promotion_promotion_batch_url(@template_promotion)
+ end
+
+ def set_template_promotion
+ @template_promotion = Spree::Promotion.templates.find(params[:template_promotion_id])
end
end
end
diff --git a/app/controllers/spree/admin/promotions_controller.rb b/app/controllers/spree/admin/promotions_controller.rb
index 4b66698654..18a81a3329 100644
--- a/app/controllers/spree/admin/promotions_controller.rb
+++ b/app/controllers/spree/admin/promotions_controller.rb
@@ -40,7 +40,7 @@ def collection
params[:q][:s] ||= 'id desc'
@collection = super
- @collection = @collection.non_batched
+ # @collection = @collection.where(template: false)
@search = @collection.ransack(params[:q])
@collection = @search.result(distinct: true).
includes(promotion_includes).
diff --git a/app/controllers/spree/admin/template_promotions_controller.rb b/app/controllers/spree/admin/template_promotions_controller.rb
new file mode 100644
index 0000000000..f8a5c92459
--- /dev/null
+++ b/app/controllers/spree/admin/template_promotions_controller.rb
@@ -0,0 +1,82 @@
+module Spree
+ module Admin
+ class TemplatePromotionsController < ResourceController
+ before_action :load_data
+
+ def create
+ invoke_callbacks(:create, :before)
+ @object.attributes = permitted_resource_params
+ @object.template = true
+ if @object.save
+ invoke_callbacks(:create, :after)
+ flash[:success] = flash_message_for(@object, :successfully_created)
+ respond_with(@object) do |format|
+ format.turbo_stream if create_turbo_stream_enabled?
+ format.html { redirect_to location_after_save }
+ format.js { render layout: false }
+ end
+ else
+ invoke_callbacks(:create, :fails)
+ respond_with(@object) do |format|
+ format.html { render action: :new, status: :unprocessable_entity }
+ format.js { render layout: false, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ private
+
+ def new_object_url(options = {})
+ spree.new_admin_template_promotion_url(options)
+ end
+
+ def collection_url(options = {})
+ spree.admin_template_promotions_url(options)
+ end
+
+ def resource
+ return @resource if @resource
+
+ parent_model_name = parent_data[:model_name] if parent_data
+ @resource = Spree::Admin::Resource.new 'admin/spree', 'template_promotions', parent_model_name, object_name
+ end
+
+ def load_data
+ @actions = Rails.application.config.spree.promotions.actions
+
+ @calculators = Rails.application.config.spree.calculators.promotion_actions_create_adjustments
+ @promotion_categories = Spree::PromotionCategory.order(:name)
+ @promotion = @object
+ end
+
+ def collection
+ return @collection if defined?(@collection)
+
+ params[:q] ||= HashWithIndifferentAccess.new
+ params[:q][:s] ||= 'id desc'
+
+ @collection = super
+ @collection = @collection.templates
+ @search = @collection.ransack(params[:q])
+ @collection = @search.result(distinct: true).
+ includes(promotion_includes).
+ page(params[:page]).
+ per(params[:per_page] || Spree::Backend::Config[:admin_promotions_per_page])
+
+ @promotions = @collection
+ end
+
+ def promotion_includes
+ [:promotion_actions]
+ end
+
+ def model_class
+ Spree::Promotion
+ end
+
+ def permitted_resource_params
+ params.require(:promotion).permit!
+ end
+ end
+ end
+end
diff --git a/app/helpers/spree/admin/navigation_helper.rb b/app/helpers/spree/admin/navigation_helper.rb
index 7b6c81a7b8..6dac1de9af 100644
--- a/app/helpers/spree/admin/navigation_helper.rb
+++ b/app/helpers/spree/admin/navigation_helper.rb
@@ -378,12 +378,16 @@ def product_properties_actions
Rails.application.config.spree_backend.actions[:product_properties]
end
+ def template_promotion_actions
+ Rails.application.config.spree_backend.actions[:template_promotion]
+ end
+
def promotion_batch_actions
- Rails.application.config.spree_backend.actions[:promotion_batch_actions]
+ Rails.application.config.spree_backend.actions[:promotion_batch]
end
def promotion_batches_actions
- Rails.application.config.spree_backend.actions[:promotion_batches_actions]
+ Rails.application.config.spree_backend.actions[:promotion_batches]
end
# rubocop:enable Metrics/ModuleLength
end
diff --git a/app/models/spree/admin/actions/promotion_batch_default_actions_builder.rb b/app/models/spree/admin/actions/promotion_batch_default_actions_builder.rb
deleted file mode 100644
index f9c7979b9d..0000000000
--- a/app/models/spree/admin/actions/promotion_batch_default_actions_builder.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-module Spree
- module Admin
- module Actions
- class PromotionBatchDefaultActionsBuilder
- include Spree::Core::Engine.routes.url_helpers
-
- def build
- root = Root.new
- export_codes_to_csv_action(root)
- root
- end
-
- private
-
- def export_codes_to_csv_action(root)
- action =
- ActionBuilder.new('csv_export', ->(resource) { csv_export_admin_promotion_batch_path(resource) }).
- with_icon_key('download.svg').
- with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
- build
-
- root.add(action)
- end
- end
- end
- end
-end
diff --git a/app/models/spree/admin/actions/promotion_batches_default_actions_builder.rb b/app/models/spree/admin/actions/promotion_batches_default_actions_builder.rb
index 79a6ea955f..03021bb42e 100644
--- a/app/models/spree/admin/actions/promotion_batches_default_actions_builder.rb
+++ b/app/models/spree/admin/actions/promotion_batches_default_actions_builder.rb
@@ -6,22 +6,49 @@ class PromotionBatchesDefaultActionsBuilder
def build
root = Root.new
- add_new_promotion_batch_action(root)
+ add_view_promotions_action(root)
+ add_import_promotion_batch_action(root)
+ add_generate_promotion_batch_action(root)
root
end
private
- def add_new_promotion_batch_action(root)
+ def add_generate_promotion_batch_action(root)
action =
- ActionBuilder.new('new_promotion_batch', new_admin_promotion_batch_path).
+ ActionBuilder.new('generate_codes', ->(template_promotion) { new_admin_template_promotion_promotion_batch_path(template_promotion_id: template_promotion.id) }).
+ with_label_translation_key('admin.promotion_batches.generate_codes').
with_icon_key('add.svg').
- with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
- with_create_ability_check(::Spree::PromotionBatch).
+ with_style(Spree::Admin::Actions::ActionStyle::PRIMARY).
+ with_create_ability_check(Spree::PromotionBatch).
build
root.add(action)
end
+
+ def add_import_promotion_batch_action(root)
+ action =
+ ActionBuilder.new('import_csv', ->(template_promotion) { import_admin_template_promotion_promotion_batches_path(template_promotion_id: template_promotion.id) }).
+ with_label_translation_key('admin.promotion_batches.import_csv').
+ with_icon_key('file-earmark-arrow-up.svg').
+ with_style(Spree::Admin::Actions::ActionStyle::LIGHT).
+ with_create_ability_check(Spree::PromotionBatch).
+ build
+
+ root.add(action)
+ end
+
+ def add_view_promotions_action(root)
+ action =
+ ActionBuilder.new('view_promotions', ->(template_promotion) { admin_promotions_path(q: { for_template_promotion_id: template_promotion.id }) }).
+ with_label_translation_key('admin.promotion_batches.view_promotions').
+ with_icon_key('list.svg').
+ with_style(Spree::Admin::Actions::ActionStyle::LIGHT).
+ with_manage_ability_check(Spree::Promotion).
+ build
+
+ root.add(action)
+ end
end
end
end
diff --git a/app/models/spree/admin/actions/template_promotion_default_actions_builder.rb b/app/models/spree/admin/actions/template_promotion_default_actions_builder.rb
new file mode 100644
index 0000000000..f452c72310
--- /dev/null
+++ b/app/models/spree/admin/actions/template_promotion_default_actions_builder.rb
@@ -0,0 +1,55 @@
+module Spree
+ module Admin
+ module Actions
+ class TemplatePromotionDefaultActionsBuilder
+ include Spree::Core::Engine.routes.url_helpers
+
+ def build
+ root = Root.new
+ add_view_promotion_batches_action(root)
+ add_import_promotion_batch_action(root)
+ add_generate_promotion_batch_action(root)
+ root
+ end
+
+ private
+
+ def add_generate_promotion_batch_action(root)
+ action =
+ ActionBuilder.new('generate_codes', ->(template_promotion) { new_admin_template_promotion_promotion_batch_path(template_promotion_id: template_promotion.id) }).
+ with_label_translation_key('admin.promotion_batches.generate_codes').
+ with_icon_key('add.svg').
+ with_style(Spree::Admin::Actions::ActionStyle::PRIMARY).
+ with_create_ability_check(Spree::PromotionBatch).
+ build
+
+ root.add(action)
+ end
+
+ def add_import_promotion_batch_action(root)
+ action =
+ ActionBuilder.new('import_csv', ->(template_promotion) { import_admin_template_promotion_promotion_batches_path(template_promotion_id: template_promotion.id) }).
+ with_label_translation_key('admin.promotion_batches.import_csv').
+ with_icon_key('file-earmark-arrow-up.svg').
+ with_style(Spree::Admin::Actions::ActionStyle::LIGHT).
+ with_create_ability_check(Spree::PromotionBatch).
+ build
+
+ root.add(action)
+ end
+
+ def add_view_promotion_batches_action(root)
+ action =
+ ActionBuilder.new('view_promotion_batches', ->(template_promotion) { admin_template_promotion_promotion_batches_path(template_promotion) }).
+ with_label_translation_key('admin.promotion_batches.view_promotions').
+ with_icon_key('list.svg').
+ with_style(Spree::Admin::Actions::ActionStyle::LIGHT).
+ with_manage_ability_check(Spree::Promotion).
+ build
+
+ root.add(action)
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/spree/admin/main_menu/default_configuration_builder.rb b/app/models/spree/admin/main_menu/default_configuration_builder.rb
index b524eaada3..5cb2fda22d 100644
--- a/app/models/spree/admin/main_menu/default_configuration_builder.rb
+++ b/app/models/spree/admin/main_menu/default_configuration_builder.rb
@@ -19,7 +19,6 @@ def build
add_integrations_section(root)
add_oauth_section(root)
add_settings_section(root)
- add_promotion_batches_section(root)
root
end
@@ -138,6 +137,10 @@ def add_promotions_section(root)
ItemBuilder.new('promotion_categories', admin_promotion_categories_path).
with_admin_ability_check(Spree::PromotionCategory).
with_label_translation_key('admin.tab.promotion_categories').
+ build,
+ ItemBuilder.new('bulk_promo_codes', admin_template_promotions_path).
+ with_admin_ability_check(Spree::Promotion, Spree::PromotionBatch).
+ with_label_translation_key('admin.tab.bulk_promo_codes').
build
]
@@ -256,13 +259,6 @@ def add_settings_section(root)
build
root.add(section)
end
-
- def add_promotion_batches_section(root)
- root.add(ItemBuilder.new('promotion_batches', admin_promotion_batches_path).
- with_icon_key('stack.svg').
- with_admin_ability_check(Spree::PromotionBatch).
- build)
- end
# rubocop:enable Metrics/AbcSize
end
# rubocop:enable Metrics/ClassLength
diff --git a/app/views/spree/admin/promotion_batches/_form.html.erb b/app/views/spree/admin/promotion_batches/_form.html.erb
index c831fea953..279ea2810a 100644
--- a/app/views/spree/admin/promotion_batches/_form.html.erb
+++ b/app/views/spree/admin/promotion_batches/_form.html.erb
@@ -1,6 +1,26 @@
-
- <%= f.field_container :template_promotion do %>
- <%= f.label :template_promotion_id, Spree.t(:template_promotion) %>
- <%= f.collection_select :template_promotion_id, Spree::Promotion.non_batched, :id, ->(promotion) { "#{promotion.name} # #{promotion.id}" }, { include_blank: true }, { class: 'select2-clear w-100' } %>
- <% end %>
+
+
+
<%= Spree.t('admin.promotion_batches.general_settings') %>
+
+ <%= label_tag :amount, Spree.t('admin.promotion_batches.amount') %>
+ <%= number_field_tag :amount, nil, class: 'form-control' %>
+
+
+
+
<%= Spree.t('admin.promotion_batches.generator_settings') %>
+
+ <%= label_tag :random_characters, Spree.t('admin.promotion_batches.random_characters') %>
+ <%= number_field_tag :random_characters, nil, class: 'form-control' %>
+
+
+
+ <%= label_tag :prefix, Spree.t('admin.promotion_batches.prefix') %>
+ <%= text_field_tag :prefix, nil, class: 'form-control' %>
+
+
+
+ <%= label_tag :suffix, Spree.t('admin.promotion_batches.suffix') %>
+ <%= text_field_tag :suffix, nil, class: 'form-control' %>
+
+
diff --git a/app/views/spree/admin/promotion_batches/edit.html.erb b/app/views/spree/admin/promotion_batches/edit.html.erb
deleted file mode 100644
index 8c1f21c7f7..0000000000
--- a/app/views/spree/admin/promotion_batches/edit.html.erb
+++ /dev/null
@@ -1,68 +0,0 @@
-<% content_for :page_title do %>
- <%= link_to Spree.t(:promotion_batches), admin_promotion_batches_path %> /
- <%= @promotion_batch.id %>
-<% end %>
-
-<% if @promotion_batch.template_promotion_id%>
-
-
- <%= form_tag csv_import_admin_promotion_batch_path, method: :post, multipart: true do %>
- <%= file_field_tag :file, accept: ".csv" %>
- <%= submit_tag Spree.t('promotion_batch_form.import_codes') %>
- <% end %>
-
-
-<% end %>
-
-<% unless @promotion_batch.template_promotion_id%>
- <%= form_for @promotion_batch, url: object_url, method: :put do |f| %>
-
-
- <%= render partial: 'form', locals: { f: f } %>
- <%= render partial: 'spree/admin/shared/edit_resource_links' %>
-
-
- <% end %>
-<% end %>
-
-<% if @promotion_batch.template_promotion_id %>
- <%= form_with url: populate_admin_promotion_batch_path(@promotion_batch), method: :post do %>
-
- <%= label_tag :batch_size do %>
- <%= number_field_tag(:batch_size) %>
- <%= Spree.t('promotion_batch_form.batch_size') %>
- <% end %>
-
-
- <%= label_tag :prefix do %>
- <%= radio_button :code, :affix, 'prefix' %>
- <%= Spree.t('promotion_batch_form.prefix') %>
- <% end %>
-
-
- <%= label_tag :suffix do %>
- <%= radio_button :code, :affix, 'suffix' %>
- <%= Spree.t('promotion_batch_form.suffix') %>
- <% end %>
-
-
- <%= label_tag :affix_content do %>
- <%= text_field_tag(:affix_content) %>
- <%= Spree.t('promotion_batch_form.affix_content') %>
- <% end %>
-
-
- <%= label_tag :forbidden_phrases do %>
- <%= text_area_tag(:forbidden_phrases) %>
- <%= Spree.t('promotion_batch_form.forbidden_phrases') %>
- <% end %>
-
-
- <%= label_tag :random_part_bytes do %>
- <%= number_field_tag(:random_part_bytes, value = 4) %>
- <%= Spree.t('promotion_batch_form.random_part_bytes') %>
- <% end %>
-
- <%= submit_tag(Spree.t('promotion_batch_form.populate')) %>
- <% end %>
-<% end %>
diff --git a/app/views/spree/admin/promotion_batches/import.html.erb b/app/views/spree/admin/promotion_batches/import.html.erb
new file mode 100644
index 0000000000..39b0c52b47
--- /dev/null
+++ b/app/views/spree/admin/promotion_batches/import.html.erb
@@ -0,0 +1,24 @@
+<% content_for :page_title do %>
+ <%= link_to Spree.t(:template_promotions), admin_template_promotions_url %> /
+ <%= link_to @template_promotion.name, edit_admin_template_promotion_url(@template_promotion) %> /
+ <%= link_to Spree.t(:promotion_batches), admin_template_promotion_promotion_batches_url(@template_promotion) %> /
+ <%= Spree.t('admin.promotion_batches.import_csv') %>
+<% end %>
+
+
+
+
+ <%= form_tag process_import_admin_template_promotion_promotion_batches_path(@template_promotion), method: :post, multipart: true do %>
+
+
+
+ <%= label_tag :file, Spree.t('admin.promotion_batches.csv_file'), class: 'form-control-file' %>
+ <%= file_field_tag :file, accept: '.csv' %>
+ <%= Spree.t('admin.promotion_batches.csv_file_notice') %>
+
+ <%= render partial: 'spree/admin/shared/new_resource_links' %>
+
+
+ <% end %>
+
+
diff --git a/app/views/spree/admin/promotion_batches/index.html.erb b/app/views/spree/admin/promotion_batches/index.html.erb
index 60b460ae49..a328042c9c 100644
--- a/app/views/spree/admin/promotion_batches/index.html.erb
+++ b/app/views/spree/admin/promotion_batches/index.html.erb
@@ -1,5 +1,7 @@
<% content_for :page_title do %>
- <%= plural_resource_name(Spree::PromotionBatch) %>
+ <%= link_to Spree.t(:template_promotions), admin_template_promotions_url %> /
+ <%= link_to @template_promotion.name, edit_admin_template_promotion_url(@template_promotion) %> /
+ <%= Spree.t(:promotion_batches) %>
<% end %>
<% content_for :page_actions do %>
@@ -7,7 +9,7 @@
<% next unless action.available?(current_ability) %>
<%= button_link_to(
Spree.t(action.label_translation_key),
- action.url,
+ action.url(@template_promotion),
class: action.classes,
icon: action.icon_key
) %>
@@ -20,26 +22,33 @@
<%= Spree.t(:id) %> |
- <%= Spree.t(:size) %> |
- <%= Spree.t(:template_promotion) %> |
+ <%= Spree.t('admin.promotion_batches.generated_codes') %> |
+ <%= Spree.t(:created_at) %> |
+ <%= Spree.t(:state) %> |
|
<% @promotion_batches.each do |promotion_batch| %>
- <%= link_to Spree::PromotionBatchPresenter.new(promotion_batch).call[:model_name_id], spree.admin_promotion_batch_path(promotion_batch) %> |
+ <%= promotion_batch.id %> |
<%= promotion_batch.promotions.count %> |
- <%= link_to Spree::PromotionBatchPresenter.new(promotion_batch).call[:template_promotion_name_id], spree.edit_admin_promotion_path(promotion_batch.template_promotion) if promotion_batch.template_promotion %> |
-
-
- <%= link_to_edit promotion_batch, no_text: true if can?(:edit, promotion_batch) %>
- <%= link_to_delete promotion_batch, no_text: true if can?(:delete, promotion_batch) %>
-
+ | <%= promotion_batch.created_at.strftime('%F %T %Z') %> |
+ <%= promotion_batch.state %> |
+
+ <%= button_link_to('', admin_promotions_path({ q: { promotion_batch_id_eq: promotion_batch.id }}), icon: 'list.svg', class: 'btn btn-light btn-sm with-tip icon-link', data: { 'original-title' => Spree.t('admin.promotion_batches.view_promotions') }) %>
+ <%= button_link_to('', admin_template_promotion_promotion_batch_export_path(template_promotion_id: @template_promotion.id, promotion_batch_id: promotion_batch.id), icon: 'file-earmark-arrow-down.svg', class: 'btn btn-light btn-sm with-tip icon-link', data: { 'original-title' => Spree.t('admin.promotion_batches.export_csv')} ) %>
|
<% end %>
-<% end %>
\ No newline at end of file
+<% else %>
+
+ <%= Spree.t(:no_resource_found, resource: plural_resource_name(Spree::PromotionBatch)) %>,
+ <%= link_to Spree.t('admin.promotion_batches.generate_codes'), new_object_url if can?(:create, Spree::PromotionBatch) %>
+ <%= Spree.t(:or) %>
+ <%= link_to Spree.t('admin.promotion_batches.import_csv'), import_admin_template_promotion_promotion_batches_path(@template_promotion) if can?(:create, Spree::PromotionBatch) %>!
+
+<% end %>
diff --git a/app/views/spree/admin/promotion_batches/new.html.erb b/app/views/spree/admin/promotion_batches/new.html.erb
index 328fe5e0c0..593775e52e 100644
--- a/app/views/spree/admin/promotion_batches/new.html.erb
+++ b/app/views/spree/admin/promotion_batches/new.html.erb
@@ -1,6 +1,8 @@
<% content_for :page_title do %>
- <%= link_to Spree.t(:promotion_batches), admin_promotion_batches_path %> /
- <%= Spree.t(:new_promotion_batch) %>
+ <%= link_to Spree.t(:template_promotions), admin_template_promotions_url %> /
+ <%= link_to @template_promotion.name, edit_admin_template_promotion_url(@template_promotion) %> /
+ <%= link_to Spree.t(:promotion_batches), admin_template_promotion_promotion_batches_url(@template_promotion) %> /
+ <%= Spree.t(:generate_codes) %>
<% end %>
diff --git a/app/views/spree/admin/promotion_batches/show.html.erb b/app/views/spree/admin/promotion_batches/show.html.erb
deleted file mode 100644
index 2bad5bdcfe..0000000000
--- a/app/views/spree/admin/promotion_batches/show.html.erb
+++ /dev/null
@@ -1,37 +0,0 @@
-<% content_for :page_title do %>
- <%= link_to Spree.t(:promotion_batches), admin_promotion_batches_path %> /
- <%= @promotion_batch.id %>
-<% end %>
-
-<% content_for :page_actions do %>
- <% promotion_batch_actions.items.each do |action| %>
- <% next unless action.available?(current_ability) %>
- <%= button_link_to(
- Spree.t(action.label_translation_key),
- action.url(@promotion_batch),
- class: action.classes,
- icon: action.icon_key
- ) %>
- <% end %>
-<% end %>
-
-
-
-
- <%= Spree.t(:code) %> |
- <%= Spree.t(:description) %> |
- <%= Spree.t(:redeemed) %> |
- <%= Spree.t(:expiration) %> |
-
-
-
- <% @promotion_batch.promotions.each do |promotion| %>
-
- <%= promotion.code %> |
- <%= promotion.description %> |
- <%= promotion.credits_count == promotion.usage_limit ? Spree.t(:say_yes) : Spree.t(:say_no) %> |
- <%= promotion.expires_at.to_date if promotion.expires_at %> |
-
- <% end %>
-
-
diff --git a/app/views/spree/admin/template_promotions/_form.html.erb b/app/views/spree/admin/template_promotions/_form.html.erb
new file mode 100644
index 0000000000..73ea5f4fad
--- /dev/null
+++ b/app/views/spree/admin/template_promotions/_form.html.erb
@@ -0,0 +1,77 @@
+<%= render partial: 'spree/admin/shared/error_messages', locals: { target: @promotion } %>
+
+
+
+ <%= f.field_container :name do %>
+ <%= f.label :name %>
+ <%= f.text_field :name, class: 'form-control' %>
+ <%= f.error_message_on :name %>
+ <% end %>
+
+ <%= f.field_container :path do %>
+ <%= f.label :path %>
+ <%= f.text_field :path, class: 'form-control' %>
+ <% end %>
+
+ <%= f.field_container :advertise, class: ['checkbox'] do %>
+ <%= f.label :advertise do %>
+ <%= f.check_box :advertise %>
+ <%= Spree.t(:advertise) %>
+ <% end %>
+ <% end %>
+
+
+
+ <%= f.field_container :description do %>
+ <%= f.label :description %>
+ <%= f.text_area :description, rows: 7, class: 'form-control' %>
+ <% end %>
+
+ <%= f.field_container :category do %>
+ <%= f.label :promotion_category %>
+ <%= f.collection_select(:promotion_category_id, @promotion_categories, :id, :name, { include_blank: Spree.t('match_choices.none') }, { class: 'select2 w-100' }) %>
+ <% end %>
+
+ <% if @stores.count > 1 %>
+ <%= f.field_container :stores do %>
+ <%= f.label :promotion_stores, Spree.t(:stores) %>
+ <%= collection_select(:promotion, :store_ids, @stores, :id, :unique_name, {}, { multiple: true, class: 'select2' }) %>
+ <% end %>
+ <% end %>
+
+
+
+
diff --git a/app/views/spree/admin/template_promotions/edit.html.erb b/app/views/spree/admin/template_promotions/edit.html.erb
new file mode 100644
index 0000000000..2a09dc07bc
--- /dev/null
+++ b/app/views/spree/admin/template_promotions/edit.html.erb
@@ -0,0 +1,42 @@
+<% content_for :page_title do %>
+ <%= link_to Spree.t(:template_promotions), admin_template_promotions_url %> /
+ <%= @promotion.name %>
+<% end %>
+
+<% content_for :page_actions do %>
+ <% template_promotion_actions.items.each do |action| %>
+ <% next unless action.available?(current_ability) %>
+ <%= button_link_to(
+ Spree.t(action.label_translation_key),
+ action.url(@promotion),
+ class: action.classes,
+ icon: action.icon_key
+ ) %>
+ <% end %>
+<% end %>
+
+<%= form_for @promotion, url: object_url, method: :put do |f| %>
+
+
+ <%= render partial: 'form', locals: { f: f } %>
+ <%= render partial: 'spree/admin/shared/edit_resource_links' %>
+
+
+
+<% end %>
+
+
+
+<%= render partial: "spree/admin/variants/autocomplete", formats: [:js] %>
diff --git a/app/views/spree/admin/template_promotions/index.html.erb b/app/views/spree/admin/template_promotions/index.html.erb
new file mode 100644
index 0000000000..d7fa9159a5
--- /dev/null
+++ b/app/views/spree/admin/template_promotions/index.html.erb
@@ -0,0 +1,71 @@
+<% content_for :page_title do %>
+ <%= Spree.t(:template_promotions) %>
+<% end %>
+
+<% content_for :page_actions do %>
+ <%= button_link_to Spree.t('admin.template_promotions.new_template'), new_object_url, class: "btn-success", icon: 'add.svg' %>
+<% end if can?(:create, Spree::Promotion) %>
+
+<% content_for :table_filter do %>
+
+ <%= search_form_for [:admin, @search] do |f| %>
+
+
+
+ <%= label_tag :q_name_cont, Spree.t(:name) %>
+ <%= f.text_field :name_cont, tabindex: 1, class: "form-control js-quick-search-target js-filterable" %>
+
+
+
+
+
+ <%= label_tag :q_promotion_category_id_eq, Spree.t(:promotion_category) %>
+ <%= f.collection_select(:promotion_category_id_eq, @promotion_categories, :id, :name, { include_blank: Spree.t('match_choices.all') }, { class: 'select2 js-filterable' }) %>
+
+
+
+
+
+ <%= button Spree.t(:filter_results), 'search.svg' %>
+
+ <% end %>
+
+<% end %>
+
+<% if @promotions.any? %>
+
+
+
+
+ <%= Spree.t(:name) %> |
+ <%= Spree.t(:description) %> |
+ <%= Spree.t('admin.template_promotions.generated_promotions') %> |
+ <%= Spree.t(:expiration) %> |
+ |
+
+
+
+ <% @promotions.each do |template| %>
+
+ <%= link_to template.name, spree.edit_admin_template_promotion_path(template) %> |
+ <%= template.description %> |
+ <%= link_to template.promotion_from_template.count, admin_template_promotion_promotion_batches_path(template) %> |
+ <%= template.expires_at.to_date if template.expires_at %> |
+
+
+ <%= link_to_edit template, no_text: true if can?(:edit, template) %>
+ <%= button_link_to '', admin_template_promotion_promotion_batches_path(template), class: 'btn btn-light btn-sm icon-link with-tip', icon: 'list.svg', data: { 'original-title' => Spree.t('admin.promotion_batches.view_promotions')} %>
+
+ |
+
+ <% end %>
+
+
+
+ <%= render 'spree/admin/shared/index_table_options', collection: @promotions, simple: true %>
+<% else %>
+
+ <%= Spree.t(:no_resource_found, resource: plural_resource_name(Spree::Promotion)) %>,
+ <%= link_to Spree.t(:add_one), new_object_url if can?(:create, Spree::Promotion) %>!
+
+<% end %>
diff --git a/app/views/spree/admin/template_promotions/new.html.erb b/app/views/spree/admin/template_promotions/new.html.erb
new file mode 100644
index 0000000000..58086c09e8
--- /dev/null
+++ b/app/views/spree/admin/template_promotions/new.html.erb
@@ -0,0 +1,13 @@
+<% content_for :page_title do %>
+ <%= link_to Spree.t(:template_promotions), admin_template_promotions_url %> /
+ <%= Spree.t('admin.template_promotions.new_template') %>
+<% end %>
+
+
+
+ <%= form_for :promotion, url: collection_url do |f| %>
+ <%= render partial: 'form', locals: { f: f } %>
+ <%= render partial: 'spree/admin/shared/new_resource_links' %>
+ <% end %>
+
+
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 435aeeda45..4bd4bef8ed 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -116,6 +116,7 @@ en:
physical: Physical
digital: Digital
tab:
+ bulk_promo_codes: Bulk Promo Codes
configuration: Configuration
content: Content
option_types: Option Types
@@ -171,6 +172,20 @@ en:
scopes: Scopes
documentation_message: 'To learn how to authenticate requests to the Platform API, '
documentation_cta: see the documentation
+ promotion_batches:
+ amount: Number of codes to generate
+ csv_file: Select a CSV file to import
+ csv_file_notice: The CSV file should include one promo code per line, without any additional columns
+ export_csv: Export CSV
+ generate_codes: Generate Codes
+ generated_codes: Generated Codes
+ general_settings: General Settings
+ generator_settings: Generator Settings
+ import_csv: Import CSV
+ prefix: (Optional) Prefix
+ random_characters: Number of random characters to generate for each code
+ suffix: (Optional) Suffix
+ view_promotions: View Promotions
reports:
for: For %{store_name}
return_authorization:
@@ -190,6 +205,9 @@ en:
customer_support_email_help: "This email is visible to your Store visitors in the Footer section"
new_order_notifications_email_help: "If you want to receive an email notification every time someone places an Order please provide an email address for that notification to be sent to"
seo_robots: "Please check
this page for more help"
+ template_promotions:
+ generated_promotions: Generated Promotions
+ new_template: New Template
user:
account: Account
addresses: Addresses
diff --git a/config/routes.rb b/config/routes.rb
index c1ee28aa19..a469e83403 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -10,11 +10,14 @@
resources :promotion_categories, except: [:show]
- resources :promotion_batches do
- member do
- get :csv_export, to: 'promotion_batches#csv_export'
- post :csv_import, to: 'promotion_batches#csv_import'
- post :populate
+ resources :template_promotions do
+ resources :promotion_batches, only: %i[index new create show] do
+ collection do
+ get :import
+ post :process_import, to: 'promotion_batches#process_import'
+ end
+
+ get :export
end
end
diff --git a/lib/spree/backend/engine.rb b/lib/spree/backend/engine.rb
index 119358659a..752aea2bb5 100644
--- a/lib/spree/backend/engine.rb
+++ b/lib/spree/backend/engine.rb
@@ -48,10 +48,9 @@ class Engine < ::Rails::Engine
Rails.application.config.spree_backend.actions[:payments] = Spree::Admin::Actions::PaymentsDefaultActionsBuilder.new.build
Rails.application.config.spree_backend.actions[:variants] = Spree::Admin::Actions::VariantsDefaultActionsBuilder.new.build
Rails.application.config.spree_backend.actions[:product_properties] = Spree::Admin::Actions::ProductPropertiesDefaultActionsBuilder.new.build
- Rails.application.config.spree_backend.actions[:promotion_batch_actions] =
- Spree::Admin::Actions::PromotionBatchDefaultActionsBuilder.new.build
- Rails.application.config.spree_backend.actions[:promotion_batches_actions] =
- Spree::Admin::Actions::PromotionBatchesDefaultActionsBuilder.new.build
+ Rails.application.config.spree_backend.actions[:template_promotion] = Spree::Admin::Actions::TemplatePromotionDefaultActionsBuilder.new.build
+ Rails.application.config.spree_backend.actions[:promotion_batch] = Spree::Admin::Actions::PromotionBatchDefaultActionsBuilder.new.build
+ Rails.application.config.spree_backend.actions[:promotion_batches] = Spree::Admin::Actions::PromotionBatchesDefaultActionsBuilder.new.build
end
end
end
diff --git a/spec/models/spree/admin/actions/promotion_batch_default_actions_builder_spec.rb b/spec/models/spree/admin/actions/promotion_batch_default_actions_builder_spec.rb
deleted file mode 100644
index 2f45ca3460..0000000000
--- a/spec/models/spree/admin/actions/promotion_batch_default_actions_builder_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require 'spec_helper'
-
-module Spree
- module Admin
- describe Actions::PromotionBatchDefaultActionsBuilder, type: :model do
- let(:builder) { described_class.new }
- let(:default_actions) do
- %w(csv_export)
- end
-
- describe '#build' do
- subject { builder.build }
-
- it 'builds default tabs' do
- expect(subject.items.map(&:key)).to match(default_actions)
- end
- end
- end
- end
-end