spree_promo 1.2.5 → 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/app/assets/javascripts/admin/promotions.js +10 -1
  2. data/app/assets/stylesheets/admin/spree_promo.css +0 -1
  3. data/app/controllers/spree/admin/promotion_actions_controller.rb +2 -2
  4. data/app/controllers/spree/admin/promotion_rules_controller.rb +2 -2
  5. data/app/controllers/spree/checkout_controller_decorator.rb +5 -16
  6. data/app/controllers/spree/orders_controller_decorator.rb +2 -18
  7. data/app/controllers/spree/store_controller_decorator.rb +55 -0
  8. data/app/models/spree/order_decorator.rb +5 -14
  9. data/app/models/spree/order_updater_decorator.rb +14 -0
  10. data/app/models/spree/promotion/actions/create_adjustment.rb +12 -22
  11. data/app/models/spree/promotion/actions/create_line_items.rb +2 -18
  12. data/app/models/spree/promotion/rules/first_order.rb +2 -19
  13. data/app/models/spree/promotion/rules/user_logged_in.rb +8 -1
  14. data/app/models/spree/promotion.rb +6 -6
  15. data/app/models/spree/promotion_action_line_item.rb +2 -0
  16. data/app/overrides/promo_admin_tabs.rb +1 -1
  17. data/app/views/spree/admin/promotion_actions/create.js.erb +6 -3
  18. data/app/views/spree/admin/promotion_actions/destroy.js.erb +1 -2
  19. data/app/views/spree/admin/promotion_rules/create.js.erb +6 -0
  20. data/app/views/spree/admin/promotion_rules/destroy.js.erb +1 -1
  21. data/app/views/spree/admin/promotions/_actions.html.erb +21 -15
  22. data/app/views/spree/admin/promotions/_form.html.erb +55 -51
  23. data/app/views/spree/admin/promotions/_promotion_action.html.erb +5 -5
  24. data/app/views/spree/admin/promotions/_promotion_rule.html.erb +5 -4
  25. data/app/views/spree/admin/promotions/_rules.html.erb +39 -26
  26. data/app/views/spree/admin/promotions/actions/_create_adjustment.html.erb +8 -9
  27. data/app/views/spree/admin/promotions/actions/_create_line_items.html.erb +19 -40
  28. data/app/views/spree/admin/promotions/edit.html.erb +22 -6
  29. data/app/views/spree/admin/promotions/index.html.erb +49 -35
  30. data/app/views/spree/admin/promotions/new.html.erb +13 -3
  31. data/app/views/spree/admin/promotions/rules/_item_total.html.erb +6 -7
  32. data/app/views/spree/admin/promotions/rules/_landing_page.html.erb +5 -8
  33. data/app/views/spree/admin/promotions/rules/_product.html.erb +7 -8
  34. data/app/views/spree/admin/promotions/rules/_user_logged_in.html.erb +0 -3
  35. data/config/locales/en.yml +8 -2
  36. data/config/routes.rb +1 -1
  37. data/db/migrate/20120831092359_spree_promo_one_two.rb +45 -0
  38. data/lib/spree/promo/engine.rb +5 -6
  39. metadata +11 -26
  40. data/app/assets/stylesheets/admin/promotions.css +0 -44
  41. data/db/migrate/20100419190933_rename_coupons_to_promotions.rb +0 -10
  42. data/db/migrate/20100426100726_create_promotion_rules.rb +0 -24
  43. data/db/migrate/20100501084722_match_policy_for_promotions.rb +0 -5
  44. data/db/migrate/20100501095202_create_promotion_rules_users.rb +0 -14
  45. data/db/migrate/20100502163939_name_for_promotions.rb +0 -5
  46. data/db/migrate/20100923095305_update_calculable_type_for_promotions.rb +0 -9
  47. data/db/migrate/20101026184833_migrate_adjustments.rb +0 -9
  48. data/db/migrate/20110331094351_promotion_changes_to_subclass_of_activator.rb +0 -22
  49. data/db/migrate/20110404123358_create_promotion_actions.rb +0 -9
  50. data/db/migrate/20110601202923_create_promotion_action_line_items.rb +0 -10
  51. data/db/migrate/20120119024707_namespace_promo_tables.rb +0 -85
  52. data/db/migrate/20120119024708_create_spree_pending_promotions.rb +0 -11
  53. data/db/migrate/20120119024721_content_visited_event.rb +0 -29
@@ -1,6 +1,15 @@
1
1
  var initProductActions = function(){
2
2
 
3
- $(".product_autocomplete").product_autocomplete();
3
+ // Add classes on promotion items for design
4
+ $('a.delete').live('mouseover mouseout', function(event) {
5
+ if (event.type == 'mouseover') {
6
+ $(this).parent().addClass('action-remove');
7
+ } else {
8
+ $(this).parent().removeClass('action-remove');
9
+ }
10
+ });
11
+
12
+ $(".variant_autocomplete").variantAutocomplete();
4
13
 
5
14
  $('.calculator-fields').each(function(){
6
15
  var $fields_container = $(this);
@@ -1,4 +1,3 @@
1
1
  /*
2
2
  *= require admin/spree_core
3
- *= require admin/promotions
4
3
  */
@@ -5,7 +5,7 @@ class Spree::Admin::PromotionActionsController < Spree::Admin::BaseController
5
5
  @promotion_action = params[:action_type].constantize.new(params[:promotion_action])
6
6
  @promotion_action.promotion = @promotion
7
7
  if @promotion_action.save
8
- flash.notice = I18n.t(:successfully_created, :resource => I18n.t(:promotion_action))
8
+ flash[:success] = I18n.t(:successfully_created, :resource => I18n.t(:promotion_action))
9
9
  end
10
10
  respond_to do |format|
11
11
  format.html { redirect_to spree.edit_admin_promotion_path(@promotion)}
@@ -17,7 +17,7 @@ class Spree::Admin::PromotionActionsController < Spree::Admin::BaseController
17
17
  @promotion = Spree::Promotion.find(params[:promotion_id])
18
18
  @promotion_action = @promotion.promotion_actions.find(params[:id])
19
19
  if @promotion_action.destroy
20
- flash.notice = I18n.t(:successfully_removed, :resource => I18n.t(:promotion_action))
20
+ flash[:success] = I18n.t(:successfully_removed, :resource => I18n.t(:promotion_action))
21
21
  end
22
22
  respond_to do |format|
23
23
  format.html { redirect_to spree.edit_admin_promotion_path(@promotion)}
@@ -10,7 +10,7 @@ class Spree::Admin::PromotionRulesController < Spree::Admin::BaseController
10
10
  @promotion_rule = promotion_rule_type.constantize.new(params[:promotion_rule])
11
11
  @promotion_rule.promotion = @promotion
12
12
  if @promotion_rule.save
13
- flash.notice = I18n.t(:successfully_created, :resource => I18n.t(:promotion_rule))
13
+ flash[:success] = I18n.t(:successfully_created, :resource => I18n.t(:promotion_rule))
14
14
  end
15
15
  respond_to do |format|
16
16
  format.html { redirect_to spree.edit_admin_promotion_path(@promotion)}
@@ -22,7 +22,7 @@ class Spree::Admin::PromotionRulesController < Spree::Admin::BaseController
22
22
  @promotion = Spree::Promotion.find(params[:promotion_id])
23
23
  @promotion_rule = @promotion.promotion_rules.find(params[:id])
24
24
  if @promotion_rule.destroy
25
- flash.notice = I18n.t(:successfully_removed, :resource => I18n.t(:promotion_rule))
25
+ flash[:success] = I18n.t(:successfully_removed, :resource => I18n.t(:promotion_rule))
26
26
  end
27
27
  respond_to do |format|
28
28
  format.html { redirect_to spree.edit_admin_promotion_path(@promotion)}
@@ -5,36 +5,25 @@ Spree::CheckoutController.class_eval do
5
5
  if @order.update_attributes(object_params)
6
6
 
7
7
  fire_event('spree.checkout.update')
8
-
9
- if @order.coupon_code.present?
10
- event_name = "spree.checkout.coupon_code_added"
11
- if promo = Spree::Promotion.with_coupon_code(@order.coupon_code).where(:event_name => event_name).first
12
- fire_event(event_name, :coupon_code => @order.coupon_code)
13
- # If it doesn't exist, raise an error!
14
- # Giving them another chance to enter a valid coupon code
15
- else
16
- flash[:error] = t(:promotion_not_found)
17
- render :edit and return
18
- end
19
- end
8
+ render :edit and return unless apply_coupon_code
20
9
 
21
10
  if @order.next
22
11
  state_callback(:after)
23
12
  else
24
13
  flash[:error] = t(:payment_processing_failed)
25
- respond_with(@order, :location => checkout_state_path(@order.state))
14
+ redirect_to checkout_state_path(@order.state)
26
15
  return
27
16
  end
28
17
 
29
18
  if @order.state == 'complete' || @order.completed?
30
19
  flash.notice = t(:order_processed_successfully)
31
20
  flash[:commerce_tracking] = 'nothing special'
32
- respond_with(@order, :location => completion_route)
21
+ redirect_to completion_route
33
22
  else
34
- respond_with(@order, :location => checkout_state_path(@order.state))
23
+ redirect_to checkout_state_path(@order.state)
35
24
  end
36
25
  else
37
- respond_with(@order) { |format| format.html { render :edit } }
26
+ render :edit
38
27
  end
39
28
  end
40
29
 
@@ -3,14 +3,8 @@ Spree::OrdersController.class_eval do
3
3
  def update
4
4
  @order = current_order
5
5
  if @order.update_attributes(params[:order])
6
- if @order.coupon_code.present?
7
- if apply_coupon_code
8
- flash[:notice] = t(:coupon_code_applied)
9
- else
10
- flash[:error] = t(:promotion_not_found)
11
- render :edit and return
12
- end
13
- end
6
+ render :edit and return unless apply_coupon_code
7
+
14
8
  @order.line_items = @order.line_items.select {|li| li.quantity > 0 }
15
9
  fire_event('spree.order.contents_changed')
16
10
  respond_with(@order) do |format|
@@ -27,14 +21,4 @@ Spree::OrdersController.class_eval do
27
21
  end
28
22
  end
29
23
 
30
- def apply_coupon_code
31
- return if @order.coupon_code.blank?
32
- if promo = Spree::Promotion.with_coupon_code(@order.coupon_code).first
33
- if promo.order_activatable?(@order)
34
- fire_event('spree.checkout.coupon_code_added', :coupon_code => @order.coupon_code)
35
- true
36
- end
37
- end
38
- end
39
-
40
24
  end
@@ -0,0 +1,55 @@
1
+ Spree::StoreController.class_eval do
2
+
3
+ protected
4
+ def apply_coupon_code
5
+ if @order.coupon_code.present?
6
+ # check if coupon code is already applied
7
+ if @order.adjustments.promotion.eligible.detect { |p| p.originator.promotion.code == @order.coupon_code }.present?
8
+ flash[:notice] = t(:coupon_code_already_applied)
9
+ true
10
+ else
11
+ event_name = "spree.checkout.coupon_code_added"
12
+
13
+ # TODO should restrict to payload's event name?
14
+ promotion = Spree::Promotion.find_by_code(@order.coupon_code)
15
+
16
+ if promotion.present?
17
+ if promotion.expired?
18
+ flash[:error] = t(:coupon_code_expired)
19
+ return false
20
+ end
21
+
22
+ if promotion.usage_limit_exceeded?
23
+ flash[:error] = t(:coupon_code_max_usage)
24
+ return false
25
+ end
26
+
27
+ previous_promo = @order.adjustments.promotion.eligible.first
28
+ fire_event(event_name, :coupon_code => @order.coupon_code)
29
+ promo = @order.adjustments.promotion.detect { |p| p.originator.promotion.code == @order.coupon_code }
30
+
31
+ if promo.present? and promo.eligible
32
+ flash[:success] = t(:coupon_code_applied)
33
+ true
34
+ elsif previous_promo.present? and promo.present?
35
+ flash[:error] = t(:coupon_code_better_exists)
36
+ false
37
+ elsif promo.present?
38
+ flash[:error] = t(:coupon_code_not_eligible)
39
+ false
40
+ else
41
+ # if the promotion was created after the order
42
+ flash[:error] = t(:coupon_code_not_found)
43
+ false
44
+ end
45
+ else
46
+ flash[:error] = t(:coupon_code_not_found)
47
+ false
48
+ end
49
+ end
50
+ else
51
+ true
52
+ end
53
+ end
54
+
55
+ end
@@ -1,6 +1,10 @@
1
1
  Spree::Order.class_eval do
2
2
  attr_accessible :coupon_code
3
- attr_accessor :coupon_code
3
+ attr_reader :coupon_code
4
+
5
+ def coupon_code=(code)
6
+ @coupon_code = code.strip.downcase rescue nil
7
+ end
4
8
 
5
9
  # Tells us if there if the specified promotion is already associated with the order
6
10
  # regardless of whether or not its currently eligible. Useful because generally
@@ -9,19 +13,6 @@ Spree::Order.class_eval do
9
13
  !! adjustments.promotion.reload.detect { |credit| credit.originator.promotion.id == promotion.id }
10
14
  end
11
15
 
12
- unless self.method_defined?('update_adjustments_with_promotion_limiting')
13
- def update_adjustments_with_promotion_limiting
14
- update_adjustments_without_promotion_limiting
15
- return if adjustments.promotion.eligible.none?
16
- most_valuable_adjustment = adjustments.promotion.eligible.max{|a,b| a.amount.abs <=> b.amount.abs}
17
- current_adjustments = (adjustments.promotion.eligible - [most_valuable_adjustment])
18
- current_adjustments.each do |adjustment|
19
- adjustment.update_attribute_without_callbacks(:eligible, false)
20
- end
21
- end
22
- alias_method_chain :update_adjustments, :promotion_limiting
23
- end
24
-
25
16
  def promo_total
26
17
  adjustments.eligible.promotion.map(&:amount).sum
27
18
  end
@@ -0,0 +1,14 @@
1
+ Spree::OrderUpdater.class_eval do
2
+ unless self.method_defined?('update_adjustments_with_promotion_limiting')
3
+ def update_adjustments_with_promotion_limiting
4
+ update_adjustments_without_promotion_limiting
5
+ return if adjustments.promotion.eligible.none?
6
+ most_valuable_adjustment = adjustments.promotion.eligible.max{|a,b| a.amount.abs <=> b.amount.abs}
7
+ current_adjustments = (adjustments.promotion.eligible - [most_valuable_adjustment])
8
+ current_adjustments.each do |adjustment|
9
+ adjustment.update_attribute_without_callbacks(:eligible, false)
10
+ end
11
+ end
12
+ alias_method_chain :update_adjustments, :promotion_limiting
13
+ end
14
+ end
@@ -1,36 +1,27 @@
1
1
  module Spree
2
2
  class Promotion
3
3
  module Actions
4
- # Responsible for the creation and management of an adjustment since an
5
- # an adjustment uses its originator to also update its eligiblity and amount
6
4
  class CreateAdjustment < PromotionAction
7
5
  calculated_adjustments
8
6
 
9
- has_many :adjustments, :as => :originator, :dependent => :destroy
10
-
11
7
  delegate :eligible?, :to => :promotion
12
8
 
13
9
  before_validation :ensure_action_has_calculator
14
10
 
15
- # Creates the adjustment related to a promotion for the order passed
16
- # through options hash
17
11
  def perform(options = {})
18
- order = options[:order]
19
- return if order.promotion_credit_exists?(self.promotion)
20
-
21
- self.create_adjustment("#{I18n.t(:promotion)} (#{promotion.name})", order, order)
12
+ return unless order = options[:order]
13
+ # Nothing to do if the promotion is already associated with the order
14
+ return if order.promotion_credit_exists?(promotion)
15
+
16
+ order.adjustments.promotion.reload.clear
17
+ order.update!
18
+ create_adjustment("#{I18n.t(:promotion)} (#{promotion.name})", order, order)
19
+ order.update!
22
20
  end
23
21
 
24
- # Override of CalculatedAdjustments#create_adjustment so promotional
25
- # adjustments are added all the time. They will get their eligibility
26
- # set to false if the amount is 0.
27
- #
28
- # Currently an adjustment is created even when its promotion is not eligible.
29
- # This helps to figure out later which adjustments should be eligible
30
- # as the order is being updated
31
- #
32
- # BTW The order is updated (through order#update) every time an adjustment
33
- # is saved
22
+ # override of CalculatedAdjustments#create_adjustment so promotional
23
+ # adjustments are added all the time. They will get their eligability
24
+ # set to false if the amount is 0
34
25
  def create_adjustment(label, target, calculable, mandatory=false)
35
26
  amount = compute_amount(calculable)
36
27
  params = { :amount => amount,
@@ -41,8 +32,7 @@ module Spree
41
32
  target.adjustments.create(params, :without_protection => true)
42
33
  end
43
34
 
44
- # Ensure a negative amount which does not exceed the sum of the order's
45
- # item_total and ship_total
35
+ # Ensure a negative amount which does not exceed the sum of the order's item_total and ship_total
46
36
  def compute_amount(calculable)
47
37
  [(calculable.item_total + calculable.ship_total), super.to_f.abs].min * -1
48
38
  end
@@ -3,14 +3,12 @@ module Spree
3
3
  module Actions
4
4
  class CreateLineItems < PromotionAction
5
5
  has_many :promotion_action_line_items, :foreign_key => :promotion_action_id
6
+ accepts_nested_attributes_for :promotion_action_line_items
7
+ attr_accessible :promotion_action_line_items_attributes
6
8
 
7
- delegate :eligible?, :to => :promotion
8
-
9
- attr_accessor :line_items_string
10
9
 
11
10
  def perform(options = {})
12
11
  return unless order = options[:order]
13
- return unless eligible?(order)
14
12
  promotion_action_line_items.each do |item|
15
13
  current_quantity = order.quantity_of(item.variant)
16
14
  if current_quantity < item.quantity
@@ -19,20 +17,6 @@ module Spree
19
17
  end
20
18
  end
21
19
  end
22
-
23
- def line_items_string
24
- promotion_action_line_items.map { |li| "#{li.variant_id}x#{li.quantity}" }.join(',')
25
- end
26
-
27
- def line_items_string=(value)
28
- promotion_action_line_items.destroy_all
29
- value.to_s.split(',').each do |str|
30
- variant_id, quantity = str.split('x')
31
- if variant_id && quantity && variant = Variant.find_by_id(variant_id)
32
- promotion_action_line_items.create({:variant => variant, :quantity => quantity.to_i}, :without_protection => true)
33
- end
34
- end
35
- end
36
20
  end
37
21
  end
38
22
  end
@@ -2,27 +2,10 @@ module Spree
2
2
  class Promotion
3
3
  module Rules
4
4
  class FirstOrder < PromotionRule
5
- attr_reader :user, :email
6
-
7
5
  def eligible?(order, options = {})
8
- @user = order.try(:user) || options[:user]
9
- @email = order.email
10
-
11
- if user || email
12
- completed_orders.blank? || (completed_orders.first == order)
13
- else
14
- false
15
- end
6
+ user = order.try(:user) || options[:user]
7
+ !!(user && user.orders.complete.count == 0)
16
8
  end
17
-
18
- private
19
- def completed_orders
20
- user ? user.orders.complete : orders_by_email
21
- end
22
-
23
- def orders_by_email
24
- Spree::Order.where(:email => email).complete
25
- end
26
9
  end
27
10
  end
28
11
  end
@@ -4,7 +4,14 @@ module Spree
4
4
  class UserLoggedIn < PromotionRule
5
5
 
6
6
  def eligible?(order, options = {})
7
- return order.try(:user).try(:anonymous?) == false
7
+ # this is tricky. We couldn't use any of the devise methods since we aren't in the controller.
8
+ # we need to rely on the controller already having done this for us.
9
+
10
+ # The thinking is that the controller should have some sense of what state
11
+ # we should be in before firing events,
12
+ # so the controller will have to set this field.
13
+
14
+ return options && options[:user_signed_in]
8
15
  end
9
16
 
10
17
  end
@@ -36,16 +36,12 @@ module Spree
36
36
  where(:advertise => true)
37
37
  end
38
38
 
39
- def self.with_coupon_code(coupon_code)
40
- search(:code_cont => coupon_code).result
41
- end
42
-
43
39
  def activate(payload)
44
40
  return unless order_activatable? payload[:order]
45
41
 
46
42
  if code.present?
47
- event_code = payload[:coupon_code].to_s.strip.downcase
48
- return unless event_code == self.code.to_s.strip.downcase
43
+ event_code = payload[:coupon_code]
44
+ return unless event_code == self.code
49
45
  end
50
46
 
51
47
  if path.present?
@@ -101,5 +97,9 @@ module Spree
101
97
  credits.count
102
98
  end
103
99
 
100
+ def code=(coupon_code)
101
+ write_attribute(:code, (coupon_code.downcase.strip rescue nil))
102
+ end
103
+
104
104
  end
105
105
  end
@@ -2,5 +2,7 @@ module Spree
2
2
  class PromotionActionLineItem < ActiveRecord::Base
3
3
  belongs_to :promotion_action, :class_name => 'Spree::Promotion::Actions::CreateLineItems'
4
4
  belongs_to :variant, :class_name => "Spree::Variant"
5
+
6
+ attr_accessible :quantity, :variant_id
5
7
  end
6
8
  end
@@ -1,6 +1,6 @@
1
1
  Deface::Override.new(:virtual_path => "spree/layouts/admin",
2
2
  :name => "promo_admin_tabs",
3
3
  :insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
4
- :text => "<%= tab(:promotions, :url => spree.admin_promotions_path) %>",
4
+ :text => "<%= tab(:promotions, :url => spree.admin_promotions_path, :icon => 'icon-bullhorn') %>",
5
5
  :disabled => false,
6
6
  :original => '3e847740dc3e7f924aba1ccb4cb00c7b841649e3')
@@ -1,9 +1,12 @@
1
1
  $('#actions').append('<%= escape_javascript( render(:partial => 'spree/admin/promotions/promotion_action', :object => @promotion_action) ) %>');
2
-
2
+ $('#actions .no-objects-found').hide();
3
3
  initProductActions();
4
4
 
5
+ <% unless Rails.env.test? %>
6
+ $('.type-select.select2').select2();
7
+ <% end %>
8
+
5
9
  $('#<%= dom_id @promotion_action %>').hide();
6
10
  $('#<%= dom_id @promotion_action %>').fadeIn();
7
11
  $('#<%= dom_id @promotion_action %> .tokeninput.products').productPicker();
8
- $('.product_autocomplete').product_autocomplete();
9
-
12
+ $('.product_autocomplete').product_autocomplete();
@@ -1,2 +1 @@
1
- $('#<%= dom_id @promotion_action %>').fadeOut().remove();
2
-
1
+ $('#<%= dom_id @promotion_action %>').fadeOut().remove();
@@ -1,7 +1,13 @@
1
1
  $('#rules').append('<%= escape_javascript( render(:partial => 'spree/admin/promotions/promotion_rule', :object => @promotion_rule) ) %>');
2
+ $('#rules .no-objects-found').hide();
3
+
2
4
  $('#<%= dom_id @promotion_rule %>').hide();
3
5
  $('#<%= dom_id @promotion_rule %>').fadeIn();
4
6
  $('#<%= dom_id @promotion_rule %> .tokeninput.products').productPicker();
5
7
  $('#<%= dom_id @promotion_rule %> .tokeninput.users').userPicker();
6
8
 
7
9
  $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
10
+
11
+ <% unless Rails.env.test? %>
12
+ $('.select_item_total.select2, .select_product.select2').select2();
13
+ <% end %>
@@ -1,3 +1,3 @@
1
1
  $('#<%= dom_id @promotion_rule %>').fadeOut().remove();
2
- $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
3
2
 
3
+ $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
@@ -1,26 +1,32 @@
1
- <fieldset id="action_fields">
2
- <legend><%= t(:promotion_actions) %></legend>
1
+ <fieldset id="action_fields" class="eight columns omega 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( Rails.application.config.spree.promotions.actions.map(&:name).map {|name| [ t("promotion_action_types.#{name.demodulize.underscore}.name"), name] } ) %>
5
+ <fieldset>
6
+ <legend align="center"><%= t(:promotion_actions) %></legend>
7
+ <div class="field">
8
+ <%= label_tag :action_type, t(:add_action_of_type)%>
9
+ <%= select_tag 'action_type', options, :class => 'select2 fullwidth' %>
10
+ </div>
11
+ <div class="filter-actions actions">
12
+ <%= button t(:add), 'icon-plus', :class => 'fullwidth' %>
13
+ </div>
14
+ </fieldset>
15
+ <% end %>
3
16
 
4
17
  <%= form_for @promotion, :url => spree.admin_promotion_path(@promotion), :method => :put do |f| %>
5
18
  <div id="actions" class="filter_list">
6
19
  <% if @promotion.actions.any? %>
7
20
  <%= render :partial => 'promotion_action', :collection => @promotion.actions %>
8
21
  <% else %>
9
- <!-- <p><%= t(:no_actions_added) %></p> -->
22
+ <div class="no-objects-found">
23
+ <%= t(:no_actions_added) %>
24
+ </div>
10
25
  <% end %>
11
26
  </div>
12
- <p class="form-buttons">
13
- <%= button t(:update) %>
14
- </p>
15
- <% end %>
16
-
17
- <%= form_tag spree.admin_promotion_promotion_actions_path(@promotion), :remote => true, :id => 'new_promotion_action_form' do %>
18
- <% options = options_for_select( Rails.application.config.spree.promotions.actions.map(&:name).map {|name| [ t("promotion_action_types.#{name.demodulize.underscore}.name"), name] } ) %>
19
- <p>
20
- <%= label_tag :action_type, t(:add_action_of_type) %>
21
- <%= select_tag 'action_type', options %>
22
- <%= submit_tag t(:add) %>
23
- </p>
27
+ <div class="filter-actions actions promotion-update">
28
+ <%= button t(:update), 'icon-refresh' %>
29
+ </div>
24
30
  <% end %>
25
31
 
26
32
  </fieldset>
@@ -1,52 +1,56 @@
1
1
  <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @promotion } %>
2
- <fieldset id="general_fields">
3
- <legend><%= t(:general) %></legend>
4
- <%= f.field_container :name do %>
5
- <%= f.label :name %><br />
6
- <%= f.text_field :name %>
7
- <% end %>
8
-
9
- <%= f.field_container :event_name do %>
10
- <%= f.label :event_name %><br />
11
- <%= f.select :event_name, Spree::Activator.event_names.map{|name| [t("events.#{name}"), name] } %>
12
- <% end %>
13
-
14
- <%= f.field_container :code do %>
15
- <%= f.label :code %><br />
16
- <%= f.text_field :code %>
17
- <% end %>
18
-
19
- <%= f.field_container :path do %>
20
- <%= f.label :path %><br />
21
- <%= f.text_field :path %>
22
- <% end %>
23
-
24
- <%= f.field_container :description do %>
25
- <%= f.label :description %><br />
26
- <%= f.text_area :description, :style => 'height:50px;' %>
27
- <% end %>
28
-
29
- <%= f.field_container :advertise do %>
30
- <%= f.check_box :advertise %>
31
- <%= f.label :advertise %>
32
- <% end %>
33
-
34
- </fieldset>
35
-
36
- <fieldset id="expiry_fields">
37
- <legend><%= t(:expiry) %></legend>
38
- <p>
39
- <%= f.label :usage_limit %><br />
40
- <%= f.text_field :usage_limit %><br/>
41
- <%= t(:current_promotion_usage, :count => @promotion.credits_count) %>
42
- </p>
43
-
44
- <p id="starts_at_field">
45
- <%= f.label :starts_at %>
46
- <%= f.text_field :starts_at, :class => 'datepicker' %>
47
- </p>
48
- <p id="expires_at_field">
49
- <%= f.label :expires_at %>
50
- <%= f.text_field :expires_at, :class => 'datepicker' %>
51
- </p>
52
- </fieldset>
2
+ <div class="row">
3
+ <div id="general_fields" class="alpha thirteen columns">
4
+ <div class="alpha four columns">
5
+ <%= f.field_container :name do %>
6
+ <%= f.label :name %>
7
+ <%= f.text_field :name, :class => 'fullwidth' %>
8
+ <% end %>
9
+
10
+ <%= f.field_container :event_name do %>
11
+ <%= f.label :event_name %>
12
+ <%= f.select :event_name, Spree::Activator.event_names.map{|name| [t("events.#{name}"), name] }, {}, {:class => 'select2 fullwidth'} %>
13
+ <% end %>
14
+
15
+ <%= f.field_container :code do %>
16
+ <%= f.label :code %>
17
+ <%= f.text_field :code, :class => 'fullwidth' %>
18
+ <% end %>
19
+
20
+ <%= f.field_container :path do %>
21
+ <%= f.label :path %>
22
+ <%= f.text_field :path, :class => 'fullwidth' %>
23
+ <% end %>
24
+
25
+ <%= f.field_container :advertise do %>
26
+ <%= f.check_box :advertise %>
27
+ <%= f.label :advertise %>
28
+ <% end %>
29
+ </div>
30
+
31
+ <div class="omega nine columns">
32
+ <%= f.field_container :description do %>
33
+ <%= f.label :description %><br />
34
+ <%= f.text_area :description, :rows => 7, :class => 'fullwidth' %>
35
+ <% end %>
36
+ </div>
37
+ </div>
38
+
39
+ <div id="expiry_fields" class="three columns omega">
40
+ <%= f.field_container :usage_limit do %>
41
+ <%= f.label :usage_limit %><br />
42
+ <%= f.number_field :usage_limit, :min => 0, :class => 'fullwidth' %><br>
43
+ <%= t(:current_promotion_usage, :count => @promotion.credits_count) %>
44
+ <% end %>
45
+
46
+ <div id="starts_at_field" class="field">
47
+ <%= f.label :starts_at %>
48
+ <%= f.text_field :starts_at, :class => 'datepicker datepicker-from fullwidth' %>
49
+ </div>
50
+
51
+ <div id="expires_at_field" class="field">
52
+ <%= f.label :expires_at %>
53
+ <%= f.text_field :expires_at, :class => 'datepicker datepicker-top fullwidth' %>
54
+ </div>
55
+ </div>
56
+ </div>
@@ -1,11 +1,11 @@
1
- <div class="promotion_action <%= promotion_action.type.to_s.demodulize.underscore %>" id="<%= dom_id promotion_action %>">
2
- <span class="delete">
3
- <%= link_to_with_icon 'cross', '', spree.admin_promotion_promotion_action_path(@promotion, promotion_action), :remote => true, :method => :delete %>
4
- </span>
1
+ <div class="promotion_action promotion-block <%= promotion_action.type.to_s.demodulize.underscore %>" id="<%= dom_id promotion_action %>">
5
2
  <% type_name = promotion_action.class.name.demodulize.underscore %>
3
+ <h6 class="promotion-title"><%= t("promotion_action_types.#{type_name}.description") %></h6>
4
+ <%= link_to_with_icon 'icon-trash', '', spree.admin_promotion_promotion_action_path(@promotion, promotion_action), :remote => true, :method => :delete, :class => 'delete' %>
5
+
6
6
  <% param_prefix = "promotion[promotion_actions_attributes][#{promotion_action.id}]" %>
7
7
  <%= hidden_field_tag "#{param_prefix}[id]", promotion_action.id %>
8
- <p><%= t("promotion_action_types.#{type_name}.description") %></p>
8
+
9
9
  <%= render :partial => "spree/admin/promotions/actions/#{type_name}",
10
10
  :locals => { :promotion_action => promotion_action, :param_prefix => param_prefix } %>
11
11
  </div>