spree_promo 1.0.0.rc2 → 1.0.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. data/app/assets/javascripts/admin/promotions.js +12 -3
  2. data/app/controllers/spree/admin/promotion_rules_controller.rb +2 -0
  3. data/app/controllers/spree/admin/promotions_controller.rb +2 -1
  4. data/app/controllers/spree/checkout_controller_decorator.rb +7 -8
  5. data/app/controllers/spree/content_controller_decorator.rb +3 -6
  6. data/app/helpers/spree/promotion_rules_helper.rb +13 -0
  7. data/app/models/spree/promotion/actions/create_adjustment.rb +16 -7
  8. data/app/models/spree/promotion/actions/create_line_items.rb +4 -1
  9. data/app/models/spree/promotion/rules/first_order.rb +2 -1
  10. data/app/models/spree/promotion.rb +29 -55
  11. data/app/models/spree/promotion_rule.rb +11 -0
  12. data/app/views/spree/admin/promotion_actions/create.js.erb +2 -1
  13. data/app/views/spree/admin/promotion_rules/create.js.erb +2 -0
  14. data/app/views/spree/admin/promotion_rules/destroy.js.erb +2 -0
  15. data/app/views/spree/admin/promotions/_actions.html.erb +1 -6
  16. data/app/views/spree/admin/promotions/_form.html.erb +5 -0
  17. data/app/views/spree/admin/promotions/_promotion_action.html.erb +5 -6
  18. data/app/views/spree/admin/promotions/_rules.html.erb +3 -3
  19. data/app/views/spree/admin/promotions/actions/_create_adjustment.html.erb +14 -6
  20. data/app/views/spree/admin/promotions/actions/_create_line_items.html.erb +2 -2
  21. data/config/locales/en.yml +2 -0
  22. data/db/migrate/20120119024707_namespace_promo_tables.rb +65 -0
  23. data/db/migrate/20120119024708_create_spree_pending_promotions.rb +11 -0
  24. data/db/migrate/20120119024721_content_visited_event.rb +29 -0
  25. data/lib/spree/promo/engine.rb +1 -7
  26. metadata +12 -11
  27. data/app/models/spree/promotion/rules/landing_page.rb +0 -16
  28. data/app/views/spree/admin/promotions/actions/_give_store_credit.html.erb +0 -6
  29. data/db/migrate/20111013155037_namespace_promo_tables.rb +0 -9
@@ -22,6 +22,8 @@ var initProductRuleSourceField = function(){
22
22
 
23
23
  var initProductActions = function(){
24
24
 
25
+ $("#add_product_name").product_autocomplete();
26
+
25
27
  $('.calculator-fields').each(function(){
26
28
  var $fields_container = $(this);
27
29
  var $type_select = $fields_container.find('.type-select');
@@ -43,7 +45,6 @@ var initProductActions = function(){
43
45
  });
44
46
  });
45
47
 
46
-
47
48
  //
48
49
  // CreateLineItems Promotion Action
49
50
  //
@@ -76,7 +77,7 @@ var initProductActions = function(){
76
77
  };
77
78
  setupRemoveLineItems();
78
79
  // Add line item to list
79
- $(".promotion_action.create_line_items button.add").live('click',function(e){
80
+ $(".promotion_action.create_line_items button.add").unbind('click').click(function(e){
80
81
  var $container = $(this).parents('.promotion_action');
81
82
  var product_name = $container.find("input[name='add_product_name']").val();
82
83
  var variant_id = $container.find("input[name='add_variant_id']").val();
@@ -86,7 +87,7 @@ var initProductActions = function(){
86
87
  var newRow = "<tr><td>" + product_name + "</td><td>" + quantity + "</td><td><img src='/assets/admin/icons/cross.png' /></td></tr>";
87
88
  $container.find('table').append(newRow);
88
89
  // Add to serialized string in hidden text field
89
- var $hiddenField = $container.find("input[type='hidden']");
90
+ var $hiddenField = $container.find(".line_items_string");
90
91
  $hiddenField.val($hiddenField.val() + "," + variant_id + "x" + quantity);
91
92
  setupRemoveLineItems();
92
93
  hideOrShowItemTables();
@@ -101,6 +102,14 @@ var initProductActions = function(){
101
102
  $(document).ready(function() {
102
103
  initProductRuleSourceField();
103
104
  initProductActions();
105
+
106
+ // toggle fields for specific events
107
+ $('#promotion_event_name').change(function() {
108
+ $('#promotion_code_field').toggle($('#promotion_event_name').val() == 'spree.checkout.coupon_code_added');
109
+ $('#promotion_path_field').toggle($('#promotion_event_name').val() == 'spree.content.visited');
110
+ });
111
+ $('#promotion_event_name').change();
112
+
104
113
  });
105
114
 
106
115
 
@@ -1,4 +1,6 @@
1
1
  class Spree::Admin::PromotionRulesController < Spree::Admin::BaseController
2
+ helper 'spree/promotion_rules'
3
+
2
4
  def create
3
5
  @promotion = Spree::Promotion.find(params[:promotion_id])
4
6
  @promotion_rule = params[:promotion_rule][:type].constantize.new(params[:promotion_rule])
@@ -2,6 +2,7 @@ module Spree
2
2
  module Admin
3
3
  class PromotionsController < ResourceController
4
4
  before_filter :load_data
5
+ helper 'spree/promotion_rules'
5
6
 
6
7
  protected
7
8
  def build_resource
@@ -21,4 +22,4 @@ module Spree
21
22
  end
22
23
  end
23
24
  end
24
- end
25
+ end
@@ -1,19 +1,17 @@
1
1
  Spree::CheckoutController.class_eval do
2
+
3
+ #TODO 90% of this method is duplicated code. DRY
2
4
  def update
3
5
  if @order.update_attributes(object_params)
4
6
 
5
7
  fire_event('spree.checkout.update')
6
8
 
7
9
  if @order.coupon_code.present?
8
- # Promotion codes are stored in the preference table
9
- # Therefore we need to do a lookup there and find if one exists
10
- #
11
- # TODO: The ActiveRecord::Base.connection.quote_column_name stuff is a bit long...
12
- # TODO: Is there a better way to do that?
13
- if Spree::Preference.where(:value => @order.coupon_code).where("#{ActiveRecord::Base.connection.quote_column_name("key")} LIKE 'spree/promotion/code/%'").present?
10
+
11
+ if Spree::Promotion.exists?(:code => @order.coupon_code)
14
12
  fire_event('spree.checkout.coupon_code_added', :coupon_code => @order.coupon_code)
15
- # If it doesn't exist, raise an error!
16
- # Giving them another chance to enter a valid coupon code
13
+ # If it doesn't exist, raise an error!
14
+ # Giving them another chance to enter a valid coupon code
17
15
  else
18
16
  flash[:error] = t(:promotion_not_found)
19
17
  render :edit and return
@@ -39,4 +37,5 @@ Spree::CheckoutController.class_eval do
39
37
  respond_with(@order) { |format| format.html { render :edit } }
40
38
  end
41
39
  end
40
+
42
41
  end
@@ -1,10 +1,7 @@
1
- # Keep a record ot all static page paths visited for promotions that require them
2
1
  Spree::ContentController.class_eval do
3
- after_filter :store_visited_path
2
+ after_filter :fire_visited_event
4
3
 
5
- def store_visited_path
6
- session[:visited_paths] ||= []
7
- path = "content/#{params[:action]}"
8
- session[:visited_paths] = (session[:visited_paths] << path).compact.uniq
4
+ def fire_visited_event
5
+ fire_event('spree.content.visited', :path => path = "content/#{params[:action]}")
9
6
  end
10
7
  end
@@ -0,0 +1,13 @@
1
+ module Spree
2
+ module PromotionRulesHelper
3
+
4
+ def options_for_promotion_rule_types(promotion)
5
+ existing = promotion.rules.map { |rule| rule.class.name }
6
+ rule_names = Rails.application.config.spree.promotions.rules.map(&:name).reject{ |r| existing.include? r }
7
+ options = rule_names.map { |name| [ t("promotion_rule_types.#{name.demodulize.underscore}.name"), name] }
8
+ options_for_select(options)
9
+ end
10
+
11
+ end
12
+ end
13
+
@@ -10,13 +10,22 @@ module Spree
10
10
  return unless order = options[:order]
11
11
  # Nothing to do if the promotion is already associated with the order
12
12
  return if order.promotion_credit_exists?(promotion)
13
- if amount = calculator.compute(order)
14
- amount = BigDecimal.new(amount.to_s)
15
- amount = order.item_total if amount > order.item_total
16
- order.adjustments.promotion.reload.clear
17
- order.update!
18
- create_adjustment("#{I18n.t(:promotion)} (#{promotion.name})", order, order)
19
- end
13
+
14
+ order.adjustments.promotion.reload.clear
15
+ order.update!
16
+ create_adjustment("#{I18n.t(:promotion)} (#{promotion.name})", order, order)
17
+ end
18
+
19
+ # override of CalculatedAdjustments#create_adjustment so promotional
20
+ # adjustments are added all the time. They will get their eligability
21
+ # set to false if the amount is 0
22
+ def create_adjustment(label, target, calculable, mandatory=false)
23
+ amount = compute_amount(calculable)
24
+ target.adjustments.create(:amount => amount,
25
+ :source => calculable,
26
+ :originator => self,
27
+ :label => label,
28
+ :mandatory => mandatory)
20
29
  end
21
30
 
22
31
  # Ensure a negative amount which does not exceed the sum of the order's item_total and ship_total
@@ -7,7 +7,10 @@ module Spree
7
7
  def perform(options = {})
8
8
  return unless order = options[:order]
9
9
  promotion_action_line_items.each do |item|
10
- order.add_variant(item.variant, item.quantity)
10
+ current_quantity = order.quantity_of(item.variant)
11
+ if current_quantity < item.quantity
12
+ order.add_variant(item.variant, item.quantity - current_quantity)
13
+ end
11
14
  end
12
15
  end
13
16
 
@@ -1,7 +1,8 @@
1
1
  module Spree
2
2
  class Promotion::Rules::FirstOrder < PromotionRule
3
3
  def eligible?(order, options = {})
4
- order.user && order.user.orders.complete.count == 0
4
+ user = order.try(:user) || options[:user]
5
+ !!(user && user.orders.complete.count == 0)
5
6
  end
6
7
  end
7
8
  end
@@ -1,16 +1,10 @@
1
1
  module Spree
2
2
  class Promotion < Spree::Activator
3
3
  MATCH_POLICIES = %w(all any)
4
+ UNACTIVATABLE_ORDER_STATES = ["complete", "awaiting_return", "returned"]
4
5
 
5
- preference :usage_limit, :integer
6
- preference :match_policy, :string, :default => MATCH_POLICIES.first
7
- preference :code, :string
8
- preference :advertise, :boolean, :default => false
9
-
10
- [:usage_limit, :match_policy, :code, :advertise].each do |field|
11
- alias_method field, "preferred_#{field}"
12
- alias_method "#{field}=", "preferred_#{field}="
13
- end
6
+ Activator.event_names << 'spree.checkout.coupon_code_added'
7
+ Activator.event_names << 'spree.content.visited'
14
8
 
15
9
  has_many :promotion_rules, :foreign_key => 'activator_id', :autosave => true, :dependent => :destroy
16
10
  alias_method :rules, :promotion_rules
@@ -20,8 +14,6 @@ module Spree
20
14
  alias_method :actions, :promotion_actions
21
15
  accepts_nested_attributes_for :promotion_actions
22
16
 
23
- after_create :update_preferences
24
-
25
17
  # TODO: This shouldn't be necessary with :autosave option but nested attribute updating of actions is broken without it
26
18
  after_save :save_rules_and_actions
27
19
  def save_rules_and_actions
@@ -29,24 +21,9 @@ module Spree
29
21
  end
30
22
 
31
23
  validates :name, :presence => true
32
- #validates :preferred_code, :presence => true, :if => lambda{|r| r.event_name == 'spree.checkout.coupon_code_added' }
33
-
34
- %w(usage_limit match_policy code advertise).each do |pref|
35
- method_name = pref.to_sym
36
- define_method method_name do
37
- get_preference(pref.to_sym)
38
- end
39
-
40
- method_name = "#{pref}=".to_sym
41
- define_method method_name do |value|
42
- unless new_record?
43
- pref = value
44
- else
45
- @preferences_hash ||= {}
46
- @preferences_hash[pref.to_sym] = value
47
- end
48
- end
49
- end
24
+ validates :code, :presence => true, :if => lambda{|r| r.event_name == 'spree.checkout.coupon_code_added' }
25
+ validates :path, :presence => true, :if => lambda{|r| r.event_name == 'spree.content.visited' }
26
+ validates :usage_limit, :numericality => { :greater_than => 0, :allow_nil => true }
50
27
 
51
28
  class << self
52
29
  def advertised
@@ -67,28 +44,30 @@ module Spree
67
44
  end
68
45
 
69
46
  def activate(payload)
70
- # Since multiple promotions could be listening we need to make sure the
71
- # event applies to this one.
72
- if eligible?(payload[:order], payload)
73
- actions.each do |action|
74
- action.perform(payload)
75
- end
47
+ return unless order_activatable? payload[:order]
48
+
49
+ if code.present?
50
+ event_code = payload[:coupon_code].to_s.strip.downcase
51
+ return unless event_code == self.code.to_s.strip.downcase
76
52
  end
77
- end
78
53
 
79
- # Whether the promotion is eligible for this particular order.
80
- def eligible?(order, options = {})
81
- return false if expired? || usage_limit_exceeded?(order)
54
+ if path.present?
55
+ return unless path == payload[:path]
56
+ end
82
57
 
83
- event_code = options[:coupon_code].to_s.strip.downcase
84
- return false unless event_code == self.code.to_s.strip.downcase
58
+ actions.each do |action|
59
+ action.perform(payload)
60
+ end
61
+ end
85
62
 
86
- rules_are_eligible?(order, options)
63
+ # called anytime order.update! happens
64
+ def eligible?(order)
65
+ return false if expired? || usage_limit_exceeded?(order)
66
+ rules_are_eligible?(order, {})
87
67
  end
88
68
 
89
69
  def rules_are_eligible?(order, options = {})
90
70
  return true if rules.none?
91
-
92
71
  eligible = lambda { |r| r.eligible?(order, options) }
93
72
  if match_policy == 'all'
94
73
  rules.all?(&eligible)
@@ -97,13 +76,19 @@ module Spree
97
76
  end
98
77
  end
99
78
 
79
+ def order_activatable?(order)
80
+ order &&
81
+ created_at.to_i < order.created_at.to_i &&
82
+ !UNACTIVATABLE_ORDER_STATES.include?(order.state)
83
+ end
84
+
100
85
  # Products assigned to all product rules
101
86
  def products
102
87
  @products ||= rules.of_type('Promotion::Rules::Product').map(&:products).flatten.uniq
103
88
  end
104
89
 
105
90
  def usage_limit_exceeded?(order = nil)
106
- preferred_usage_limit.present? && preferred_usage_limit.to_i > 0 && adjusted_credits_count(order) >= preferred_usage_limit.to_i
91
+ usage_limit.present? && usage_limit > 0 && adjusted_credits_count(order) >= usage_limit
107
92
  end
108
93
 
109
94
  def adjusted_credits_count(order)
@@ -119,16 +104,5 @@ module Spree
119
104
  credits.count
120
105
  end
121
106
 
122
-
123
- private
124
-
125
- def update_preferences
126
- if @preferences_hash.present? && !@preferences_hash.empty?
127
- @preferences_hash.each do |key, value|
128
- pref_key = "spree/promotion/#{key}/#{self.id}"
129
- Spree::Preference.create(:value => value, :key => pref_key)
130
- end
131
- end
132
- end
133
107
  end
134
108
  end
@@ -5,8 +5,19 @@ module Spree
5
5
 
6
6
  scope :of_type, lambda {|t| {:conditions => {:type => t}}}
7
7
 
8
+ validate :promotion, :presence => true
9
+ validate :unique_per_activator, :on => :create
10
+
8
11
  def eligible?(order, options = {})
9
12
  raise 'eligible? should be implemented in a sub-class of Promotion::PromotionRule'
10
13
  end
14
+
15
+ private
16
+ def unique_per_activator
17
+ if Spree::PromotionRule.exists?(:activator_id => activator_id, :type => self.class.name)
18
+ errors[:base] << "Promotion already contains this rule type"
19
+ end
20
+ end
21
+
11
22
  end
12
23
  end
@@ -1,4 +1,5 @@
1
- $('#actions_container').html('<%= escape_javascript( render(:partial => 'spree/admin/promotions/actions') ) %>');
1
+ $('#actions').append('<%= escape_javascript( render(:partial => 'spree/admin/promotions/promotion_action', :object => @promotion_action) ) %>');
2
+
2
3
  initProductActions();
3
4
 
4
5
  $('#<%= dom_id @promotion_action %>').hide();
@@ -4,3 +4,5 @@ $('#<%= dom_id @promotion_rule %>').fadeIn();
4
4
  initProductRuleSourceField();
5
5
  $('#<%= dom_id @promotion_rule %> .tokeninput.products').productPicker();
6
6
  $('#<%= dom_id @promotion_rule %> .tokeninput.users').userPicker();
7
+
8
+ $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
@@ -1 +1,3 @@
1
1
  $('#<%= dom_id @promotion_rule %>').fadeOut().remove();
2
+ $('#promotion_rule_type').html('<%= escape_javascript options_for_promotion_rule_types(@promotion) %>');
3
+
@@ -4,12 +4,7 @@
4
4
  <%= form_for @promotion, :url => spree.admin_promotion_path(@promotion), :method => :put do |f| %>
5
5
  <div id="actions" class="filter_list">
6
6
  <% if @promotion.actions.any? %>
7
- <%#= render :partial => 'promotion_action', :collection => @promotion.actions, :locals => {:f => f} %>
8
-
9
- <%= f.fields_for :promotion_actions do |action_form| %>
10
- <%= render :partial => 'spree/admin/promotions/promotion_action', :locals => { :action_form => action_form } %>
11
- <% end %>
12
-
7
+ <%= render :partial => 'promotion_action', :collection => @promotion.actions %>
13
8
  <% else %>
14
9
  <!-- <p><%= t(:no_actions_added) %></p> -->
15
10
  <% end %>
@@ -16,6 +16,11 @@
16
16
  <%= f.text_field :code %>
17
17
  <% end %>
18
18
 
19
+ <%= f.field_container :path do %>
20
+ <%= f.label :path, t(:path) %><br />
21
+ <%= f.text_field :path %>
22
+ <% end %>
23
+
19
24
  <%= f.field_container :description do %>
20
25
  <%= f.label :description %><br />
21
26
  <%= f.text_area :description, :style => 'height:50px;' %>
@@ -1,12 +1,11 @@
1
- <% promotion_action = action_form.object %>
2
- <div class="promotion_action <%= promotion_action.type.demodulize.underscore %>" id="<%= dom_id promotion_action %>">
1
+ <div class="promotion_action <%= promotion_action.type.to_s.demodulize.underscore %>" id="<%= dom_id promotion_action %>">
3
2
  <span class="delete">
4
3
  <%= link_to_with_icon 'cross', '', spree.admin_promotion_promotion_action_path(@promotion, promotion_action), :remote => true, :method => :delete %>
5
4
  </span>
6
5
  <% type_name = promotion_action.class.name.demodulize.underscore %>
7
6
  <% param_prefix = "promotion[promotion_actions_attributes][#{promotion_action.id}]" %>
8
- <%#= hidden_field_tag "#{param_prefix}[id]", promotion_action.id %>
7
+ <%= hidden_field_tag "#{param_prefix}[id]", promotion_action.id %>
9
8
  <p><%= t("promotion_action_types.#{type_name}.description") %></p>
10
-
11
- <%= render :partial => "spree/admin/promotions/actions/#{type_name}", :locals => { :action_form => action_form, :promotion_action => promotion_action, :param_prefix => param_prefix } %>
12
- </div>
9
+ <%= render :partial => "spree/admin/promotions/actions/#{type_name}",
10
+ :locals => { :promotion_action => promotion_action, :param_prefix => param_prefix } %>
11
+ </div>
@@ -4,7 +4,7 @@
4
4
  <%= form_for @promotion, :url => object_url, :method => :put do |f| %>
5
5
  <p>
6
6
  <% Spree::Promotion::MATCH_POLICIES.each do |policy| %>
7
- <label><%= f.radio_button :preferred_match_policy, policy %> <%= t "promotion_form.match_policies.#{policy}" %></label> &nbsp;
7
+ <label><%= f.radio_button :match_policy, policy %> <%= t "promotion_form.match_policies.#{policy}" %></label> &nbsp;
8
8
  <% end %>
9
9
  </p>
10
10
  <div id="rules" class="filter_list">
@@ -21,10 +21,10 @@
21
21
 
22
22
  <%= form_tag spree.admin_promotion_promotion_rules_path(@promotion), :remote => true,
23
23
  :id => 'new_product_rule_form' do %>
24
- <% options = options_for_select( Rails.application.config.spree.promotions.rules.map(&:name).map {|name| [ t("promotion_rule_types.#{name.demodulize.underscore}.name"), name] } ) %>
24
+
25
25
  <p>
26
26
  <%= label_tag :promotion_rule_type, t(:add_rule_of_type) %>
27
- <%= select_tag('promotion_rule[type]', options) %>
27
+ <%= select_tag('promotion_rule[type]', options_for_promotion_rule_types(@promotion)) %>
28
28
  <%= submit_tag t(:add) %>
29
29
  </p>
30
30
  <% end %>
@@ -1,8 +1,11 @@
1
1
  <div class="calculator-fields">
2
2
 
3
3
  <p class="field">
4
- <%= action_form.label :calculator_type, t(:calculator) %>
5
- <%= action_form.collection_select :calculator_type, @calculators, :to_s, :description, {}, {:class => 'type-select'} %>
4
+ <% field_name = "#{param_prefix}[calculator_type]" %>
5
+ <%= label_tag field_name, t(:calculator) %>
6
+ <%= select_tag field_name,
7
+ options_from_collection_for_select(@calculators, :to_s, :description, promotion_action.calculator.type),
8
+ :class => 'type-select' %>
6
9
  <% if promotion_action.calculator.respond_to?(:preferences) %>
7
10
  &nbsp; <span class="warning"><%= t(:calculator_settings_warning) %></span>
8
11
  <% end %>
@@ -10,10 +13,15 @@
10
13
 
11
14
  <% unless promotion_action.new_record? %>
12
15
  <div class="settings">
13
- <%= action_form.fields_for :calculator, promotion_action.calculator do |calculator_form| %>
14
- <%= preference_fields(promotion_action.calculator, calculator_form) %>
15
- <% end %>
16
+ <% promotion_action.calculator.preferences.keys.map do |key| %>
17
+ <% field_name = "#{param_prefix}[calculator_attributes][preferred_#{key}]" %>
18
+ <%= label_tag field_name, key.to_s.titleize %>
19
+ <%= preference_field_tag(field_name,
20
+ promotion_action.calculator.get_preference(key),
21
+ :type => promotion_action.calculator.preference_type(key)) %>
22
+ <% end %>
23
+ <%= hidden_field_tag "#{param_prefix}[calculator_attributes][id]", promotion_action.calculator.id %>
16
24
  </div>
17
25
  <% end %>
18
26
 
19
- </div>
27
+ </div>
@@ -19,7 +19,8 @@
19
19
  <% end %>
20
20
  </table>
21
21
 
22
- <%= action_form.hidden_field :line_items_string %>
22
+ <%= hidden_field_tag "#{param_prefix}[line_items_string]", promotion_action.line_items_string,
23
+ :class => 'line_items_string' %>
23
24
 
24
25
  <div class="add-line-item">
25
26
  <fieldset>
@@ -38,6 +39,5 @@
38
39
  &nbsp;<br />
39
40
  <button class="add small"> <%= t(:add) %></button>
40
41
  </div>
41
-
42
42
  </fieldset>
43
43
  </div>
@@ -19,6 +19,8 @@ en:
19
19
  spree:
20
20
  checkout:
21
21
  coupon_code_added: Coupon code added
22
+ content:
23
+ visited: Visit static content page
22
24
  expiry: Expiry
23
25
  free_shipping: Free Shipping
24
26
  new_promotion: New Promotion
@@ -0,0 +1,65 @@
1
+ class NamespacePromoTables < ActiveRecord::Migration
2
+ def self.up
3
+ # namespace promo tables
4
+ rename_table :promotion_actions, :spree_promotion_actions
5
+ rename_table :promotion_rules, :spree_promotion_rules
6
+ rename_table :promotion_rules_users, :spree_promotion_rules_users
7
+ rename_table :promotion_action_line_items, :spree_promotion_action_line_items
8
+ rename_table :products_promotion_rules, :spree_products_promotion_rules
9
+
10
+ # add old promo preferences as columns
11
+ add_column :spree_activators, :usage_limit, :integer
12
+ add_column :spree_activators, :match_policy, :string, :default => 'all'
13
+ add_column :spree_activators, :code, :string
14
+ add_column :spree_activators, :advertise, :boolean, :default => false
15
+
16
+ Spree::Promotion.class_eval do
17
+ preference :usage_limit, :integer
18
+ preference :match_policy, :string, :default => 'all'
19
+ preference :code, :string
20
+ preference :advertise, :boolean, :default => false
21
+ end
22
+
23
+ # manually update old promotions to use the new promotion style
24
+ Spree::Preference.where(:owner_type => 'Spree::Activator').group_by(&:owner_id).each do |key, pref_group|
25
+ @promo = Spree::Promotion.new
26
+ pref_group.each do |pref|
27
+ case pref.name
28
+ when 'code'
29
+ @promo.code = pref.value.to_s
30
+ @promo.name = pref.value.to_s
31
+ when 'advertise'
32
+ @promo.advertise = pref.value
33
+ when 'usage_limit'
34
+ @promo.usage_limit = pref.value
35
+ when 'match_policy'
36
+ @promo.match_policy = pref.value
37
+ end
38
+ @promo.event_name = Spree::Promotion.find(pref.owner_id).event_name
39
+ end
40
+ @promo.save!
41
+ end
42
+
43
+ # Remove old promotions
44
+ Spree::Promotion.where(:code => nil).delete_all
45
+
46
+ # This *should* be in the new_preferences migration inside of Core but...
47
+ # This is migration needs to have these keys around so that
48
+ # we can convert the promotions over correctly.
49
+ # So they hang around until we're *finally* done with them, since promo's
50
+ # migrations are copied over *after* core, and then we ditch them.
51
+ remove_column :spree_preferences, :name
52
+ remove_column :spree_preferences, :owner_id
53
+ remove_column :spree_preferences, :owner_type
54
+ remove_column :spree_preferences, :group_id
55
+ remove_column :spree_preferences, :group_type
56
+ end
57
+
58
+ def self.down
59
+ rename_table :spree_promotion_actions, :promotion_actions
60
+ rename_table :spree_promotion_rules, :promotion_rules
61
+ rename_table :spree_promotion_rules_users, :promotion_rules_users
62
+ rename_table :spree_promotion_action_line_items, :promotion_action_line_items
63
+ rename_table :spree_products_promotion_rules, :products_promotion_rules
64
+ end
65
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSpreePendingPromotions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_pending_promotions do |t|
4
+ t.references :user
5
+ t.references :promotion
6
+ end
7
+
8
+ add_index :spree_pending_promotions, :user_id
9
+ add_index :spree_pending_promotions, :promotion_id
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # LandingPage used to support static pages, we've moved to a static
2
+ # event. This adds path to promotions then migrates the old LandingPage rules
3
+ class ContentVisitedEvent < ActiveRecord::Migration
4
+
5
+ # Removed Class for Migrations
6
+ class Spree::Promotion::Rules::LandingPage < Spree::PromotionRule
7
+ preference :path, :string
8
+ def eligible?(order, options = {})
9
+ true
10
+ end
11
+ end
12
+
13
+ def up
14
+ add_column :spree_activators, :path, :string
15
+
16
+ Spree::Promotion::Rules::LandingPage.all.each do |promotion_rule|
17
+ promotion = promotion_rule.promotion
18
+ say "migrating #{promotion.name} promotion to use 'spree.content.visited' event"
19
+ promotion.event_name = 'spree.content.visited'
20
+ promotion.path = promotion_rule.preferred_path
21
+ promotion.promotion_rules.delete promotion_rule
22
+ promotion.save(:validate => false)
23
+ end
24
+ end
25
+
26
+ def down
27
+ remove_column :spree_activators, :path
28
+ end
29
+ end
@@ -13,12 +13,6 @@ module Spree
13
13
  Rails.configuration.cache_classes ? require(c) : load(c)
14
14
  end
15
15
 
16
- # Include list of visited paths in notification payload hash
17
- Spree::Core::ControllerHelpers::InstanceMethods.class_eval do
18
- def default_notification_payload
19
- { :user => current_user, :order => current_order, :visited_paths => session[:visited_paths] }
20
- end
21
- end
22
16
  end
23
17
 
24
18
  config.autoload_paths += %W(#{config.root}/lib)
@@ -46,7 +40,6 @@ module Spree
46
40
  Spree::Promotion::Rules::Product,
47
41
  Spree::Promotion::Rules::User,
48
42
  Spree::Promotion::Rules::FirstOrder,
49
- Spree::Promotion::Rules::LandingPage,
50
43
  Spree::Promotion::Rules::UserLoggedIn]
51
44
  end
52
45
 
@@ -54,6 +47,7 @@ module Spree
54
47
  app.config.spree.promotions.actions = [Spree::Promotion::Actions::CreateAdjustment,
55
48
  Spree::Promotion::Actions::CreateLineItems]
56
49
  end
50
+
57
51
  end
58
52
  end
59
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_promo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc2
4
+ version: 1.0.0.rc3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,30 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-14 00:00:00.000000000Z
12
+ date: 2012-01-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: spree_core
16
- requirement: &70362724534240 !ruby/object:Gem::Requirement
16
+ requirement: &70260369514180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - =
20
20
  - !ruby/object:Gem::Version
21
- version: 1.0.0.rc2
21
+ version: 1.0.0.rc3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70362724534240
24
+ version_requirements: *70260369514180
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: spree_auth
27
- requirement: &70362724533380 !ruby/object:Gem::Requirement
27
+ requirement: &70260369513500 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
31
31
  - !ruby/object:Gem::Version
32
- version: 1.0.0.rc2
32
+ version: 1.0.0.rc3
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70362724533380
35
+ version_requirements: *70260369513500
36
36
  description: Required dependency for Spree
37
37
  email: david@spreecommerce.com
38
38
  executables: []
@@ -52,6 +52,7 @@ files:
52
52
  - app/controllers/spree/checkout_controller_decorator.rb
53
53
  - app/controllers/spree/content_controller_decorator.rb
54
54
  - app/controllers/spree/orders_controller_decorator.rb
55
+ - app/helpers/spree/promotion_rules_helper.rb
55
56
  - app/models/spree/adjustment_decorator.rb
56
57
  - app/models/spree/calculator/free_shipping.rb
57
58
  - app/models/spree/order_decorator.rb
@@ -61,7 +62,6 @@ files:
61
62
  - app/models/spree/promotion/actions/create_line_items.rb
62
63
  - app/models/spree/promotion/rules/first_order.rb
63
64
  - app/models/spree/promotion/rules/item_total.rb
64
- - app/models/spree/promotion/rules/landing_page.rb
65
65
  - app/models/spree/promotion/rules/product.rb
66
66
  - app/models/spree/promotion/rules/user.rb
67
67
  - app/models/spree/promotion/rules/user_logged_in.rb
@@ -84,7 +84,6 @@ files:
84
84
  - app/views/spree/admin/promotions/_tab.html.erb
85
85
  - app/views/spree/admin/promotions/actions/_create_adjustment.html.erb
86
86
  - app/views/spree/admin/promotions/actions/_create_line_items.html.erb
87
- - app/views/spree/admin/promotions/actions/_give_store_credit.html.erb
88
87
  - app/views/spree/admin/promotions/edit.html.erb
89
88
  - app/views/spree/admin/promotions/index.html.erb
90
89
  - app/views/spree/admin/promotions/new.html.erb
@@ -112,7 +111,9 @@ files:
112
111
  - db/migrate/20110331094351_promotion_changes_to_subclass_of_activator.rb
113
112
  - db/migrate/20110404123358_create_promotion_actions.rb
114
113
  - db/migrate/20110601202923_create_promotion_action_line_items.rb
115
- - db/migrate/20111013155037_namespace_promo_tables.rb
114
+ - db/migrate/20120119024707_namespace_promo_tables.rb
115
+ - db/migrate/20120119024708_create_spree_pending_promotions.rb
116
+ - db/migrate/20120119024721_content_visited_event.rb
116
117
  homepage: http://spreecommerce.com
117
118
  licenses: []
118
119
  post_install_message:
@@ -1,16 +0,0 @@
1
- # A rule to limit a promotion to a specific user.
2
- module Spree
3
- class Promotion::Rules::LandingPage < PromotionRule
4
- preference :path, :string
5
-
6
- def eligible?(order, options = {})
7
- if options.has_key?(:visited_paths)
8
- options[:visited_paths].to_a.any? do |path|
9
- path == preferred_path
10
- end
11
- else
12
- true
13
- end
14
- end
15
- end
16
- end
@@ -1,6 +0,0 @@
1
- <p class="field">
2
- <label for="<%= "#{param_prefix}_preferred_amount" %>">
3
- <%= t(:amount) %>
4
- <%= action_form.text_field :preferred_amount, :size => 10 %>
5
- </label>
6
- </p>
@@ -1,9 +0,0 @@
1
- class NamespacePromoTables < ActiveRecord::Migration
2
- def change
3
- rename_table :promotion_actions, :spree_promotion_actions
4
- rename_table :promotion_rules, :spree_promotion_rules
5
- rename_table :promotion_rules_users, :spree_promotion_rules_users
6
- rename_table :promotion_action_line_items, :spree_promotion_action_line_items
7
- rename_table :products_promotion_rules, :spree_products_promotion_rules
8
- end
9
- end