From 4c74f4acd70afe546a61ec30dad9d3a6e5629a95 Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Thu, 18 Jan 2024 15:00:34 +0100 Subject: [PATCH] Add admin UI for promotion code batches This was somehow missed in the past. Fixes #93 --- .../admin/base_controller.rb | 4 ++ .../promotion_code_batches_controller.rb | 12 ++++ .../_form_fields.html.erb | 22 +++++++ .../promotion_code_batches/download.csv.ruby | 8 +++ .../promotion_code_batches/index.html.erb | 65 +++++++++++++++++++ .../admin/promotion_code_batches/new.html.erb | 8 +++ friendly_promotions/config/locales/en.yml | 6 ++ .../promotion_spec.rb | 1 + .../admin/promotion_code_batches_spec.rb | 46 +++++++++++++ 9 files changed, 172 insertions(+) create mode 100644 friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/_form_fields.html.erb create mode 100644 friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/download.csv.ruby create mode 100644 friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/index.html.erb create mode 100644 friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/new.html.erb create mode 100644 friendly_promotions/spec/system/solidus_friendly_promotions/admin/promotion_code_batches_spec.rb diff --git a/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/base_controller.rb b/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/base_controller.rb index 15b483dd..92953f16 100644 --- a/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/base_controller.rb +++ b/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/base_controller.rb @@ -49,6 +49,10 @@ def collection_url(options = {}) def routes_proxy solidus_friendly_promotions end + + def parent_model_name + self.class.parent_data[:model_name].gsub("solidus_friendly_promotions/", "") + end end end end diff --git a/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/promotion_code_batches_controller.rb b/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/promotion_code_batches_controller.rb index 7361d860..796e36b2 100644 --- a/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/promotion_code_batches_controller.rb +++ b/friendly_promotions/app/controllers/solidus_friendly_promotions/admin/promotion_code_batches_controller.rb @@ -25,6 +25,18 @@ def download def build_promotion_code_batch @promotion_code_batch.process end + + def model_class + SolidusFriendlyPromotions::PromotionCodeBatch + end + + def collection + parent.code_batches + end + + def build_resource + parent.code_batches.build + end end end end diff --git a/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/_form_fields.html.erb b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/_form_fields.html.erb new file mode 100644 index 00000000..e499f986 --- /dev/null +++ b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/_form_fields.html.erb @@ -0,0 +1,22 @@ +
+ <%= batch.label :base_code, class: "required" %> + <%= batch.text_field :base_code, class: "fullwidth", required: true %> +
+
+ <%= batch.label :number_of_codes, class: "required" %> + <%= batch.number_field :number_of_codes, class: "fullwidth", min: 1, required: true %> +
+
+ <%= batch.label :join_characters %> + <%= batch.text_field :join_characters, class: "fullwidth" %> +
+<% unless promotion_id %> +
+ <%= f.label :per_code_usage_limit %> + <%= f.text_field :per_code_usage_limit, class: "fullwidth" %> +
+<% end %> +
+ <%= batch.label :email %> + <%= batch.text_field :email, class: "fullwidth" %> +
diff --git a/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/download.csv.ruby b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/download.csv.ruby new file mode 100644 index 00000000..7b3e70ef --- /dev/null +++ b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/download.csv.ruby @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +CSV.generate do |csv| + csv << ["Code"] + @promotion_code_batch.promotion_codes.order(:id).pluck(:value).each do |value| + csv << [value] + end +end diff --git a/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/index.html.erb b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/index.html.erb new file mode 100644 index 00000000..da03ee2a --- /dev/null +++ b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/index.html.erb @@ -0,0 +1,65 @@ +<% admin_breadcrumb(link_to plural_resource_name(SolidusFriendlyPromotions::Promotion), solidus_friendly_promotions.admin_promotions_path) %> +<% admin_breadcrumb(link_to @promotion.name, solidus_friendly_promotions.edit_admin_promotion_path(@promotion.id)) %> +<% admin_breadcrumb(plural_resource_name(SolidusFriendlyPromotions::PromotionCodeBatch)) %> + +<% content_for :page_actions do %> +
  • + <% if can?(:create, SolidusFriendlyPromotions::PromotionCodeBatch) %> + <%= link_to t('solidus_friendly_promotions.new_promotion_code_batch'), new_object_url, class: 'btn btn-primary' %> + <% end %> +
  • +<% end %> + +<% if @promotion_code_batches.any? %> + + + + + + + + + + + <% @promotion_code_batches.each do |promotion_code_batch| %> + + + + + + + <% end %> + +
    <%= SolidusFriendlyPromotions::PromotionCodeBatch.human_attribute_name(:base_code) %><%= SolidusFriendlyPromotions::PromotionCodeBatch.human_attribute_name(:total_codes) %><%= SolidusFriendlyPromotions::PromotionCodeBatch.human_attribute_name(:status) %><%= SolidusFriendlyPromotions::PromotionCodeBatch.human_attribute_name(:email) %>
    <%= promotion_code_batch.base_code %><%= promotion_code_batch.number_of_codes %> + <% if promotion_code_batch.error.present? %> + <%= t( + "solidus_friendly_promotions.promotion_code_batches.errored", + error: promotion_code_batch.error + ) %> + <% elsif promotion_code_batch.finished? %> + <%= t( + "solidus_friendly_promotions.promotion_code_batches.finished", + number_of_codes: promotion_code_batch.number_of_codes + ) %> + <%= link_to( + t('solidus_friendly_promotions.download_promotion_codes_list'), + admin_promotion_promotion_code_batch_download_path( + promotion_code_batch_id: promotion_code_batch.id, + format: :csv + ) + ) %> + <% else %> + <%= t( + "solidus_friendly_promotions.promotion_code_batches.processing", + number_of_codes: promotion_code_batch.number_of_codes, + number_of_codes_processed: promotion_code_batch.promotion_codes.count + ) %> + <% end %> + <%= promotion_code_batch.email %>
    +<% else %> +
    + <%= render 'spree/admin/shared/no_objects_found', + resource: SolidusFriendlyPromotions::PromotionCodeBatch, + new_resource_url: new_object_url %> +
    +<% end %> diff --git a/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/new.html.erb b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/new.html.erb new file mode 100644 index 00000000..cfb8b714 --- /dev/null +++ b/friendly_promotions/app/views/solidus_friendly_promotions/admin/promotion_code_batches/new.html.erb @@ -0,0 +1,8 @@ +<% admin_breadcrumb(link_to plural_resource_name(Spree::Promotion), spree.admin_promotions_path) %> +<% admin_breadcrumb(link_to @promotion.name, spree.admin_promotion_path(@promotion.id)) %> +<% admin_breadcrumb(plural_resource_name(Spree::PromotionCodeBatch)) %> +<%= form_for :promotion_code_batch, url: collection_url do |batch| %> + <%= batch.hidden_field :promotion_id, value: params[:promotion_id] %> + <%= render partial: 'form_fields', locals: {batch: batch, promotion_id: params[:promotion_id]} %> + <%= batch.submit t('spree.actions.create'), class: 'btn btn-primary' %> +<% end %> diff --git a/friendly_promotions/config/locales/en.yml b/friendly_promotions/config/locales/en.yml index 774235bf..8c85ab8c 100644 --- a/friendly_promotions/config/locales/en.yml +++ b/friendly_promotions/config/locales/en.yml @@ -39,6 +39,9 @@ en: no_rules_added: No Rules Added promotion_successfully_created: Promotion has been successfully created! promotion_total_changed_before_complete: One or more of the promotions on your order have become ineligible and were removed. Please check the new order amounts and try again. + promotion_code_batches: + finished: Finished + errored: Errored view_promotion_codes_list: View codes list promotion_rules: line_item_product: @@ -190,6 +193,9 @@ en: solidus_friendly_promotions/rules/user: User solidus_friendly_promotions/rules/user_logged_in: User Logged In solidus_friendly_promotions/rules/user_role: User Role(s) + solidus_friendly_promotions/promotion_code_batch: + one: Code batch + other: Code batches attributes: solidus_friendly_promotions/promotion: active: Active diff --git a/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_spec.rb b/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_spec.rb index 75d2ab8b..7aa8fd47 100644 --- a/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_spec.rb +++ b/friendly_promotions/spec/models/solidus_friendly_promotions/promotion_spec.rb @@ -9,6 +9,7 @@ it { is_expected.to respond_to(:customer_label) } it { is_expected.to have_many :rules } it { is_expected.to have_many(:order_promotions).dependent(:destroy) } + it { is_expected.to have_many(:code_batches).dependent(:destroy) } describe "lane" do it { is_expected.to respond_to(:lane) } diff --git a/friendly_promotions/spec/system/solidus_friendly_promotions/admin/promotion_code_batches_spec.rb b/friendly_promotions/spec/system/solidus_friendly_promotions/admin/promotion_code_batches_spec.rb new file mode 100644 index 00000000..ba51a87a --- /dev/null +++ b/friendly_promotions/spec/system/solidus_friendly_promotions/admin/promotion_code_batches_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "spec_helper" + +feature "Promotion Code Batches", partial_double_verification: false do + stub_authorization! + + describe "create" do + let(:promotion) { create :friendly_promotion } + + before do + allow_any_instance_of(ApplicationController).to receive(:spree_current_user) { build(:user, id: 123) } + visit solidus_friendly_promotions.new_admin_promotion_promotion_code_batch_path(promotion) + end + + def create_code_batch + fill_in "Base code", with: "base" + fill_in "Number of codes", with: 3 + click_button "Create" + end + + it "renders partial without 'Per code usage limit' " do + expect(page).to_not have_field("promotion_per_code_usage_limit") + end + + it "creates a new promotion code batch and disables the submit button", :js do + create_code_batch + + expect(page).to have_content "Code batch has been successfully created!" + + visit solidus_friendly_promotions.new_admin_promotion_promotion_code_batch_path(promotion) + + page.execute_script <<~JS + document.querySelectorAll('form').forEach(function(element) { + addEventListener('submit', function(element) { + element.preventDefault(); + }) + }); + JS + + create_code_batch + + expect(page).to have_button("Create", disabled: true) + end + end +end