spree_promo 1.0.0.rc2 → 1.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/admin/promotions.js +12 -3
- data/app/controllers/spree/admin/promotion_rules_controller.rb +2 -0
- data/app/controllers/spree/admin/promotions_controller.rb +2 -1
- data/app/controllers/spree/checkout_controller_decorator.rb +7 -8
- data/app/controllers/spree/content_controller_decorator.rb +3 -6
- data/app/helpers/spree/promotion_rules_helper.rb +13 -0
- data/app/models/spree/promotion/actions/create_adjustment.rb +16 -7
- data/app/models/spree/promotion/actions/create_line_items.rb +4 -1
- data/app/models/spree/promotion/rules/first_order.rb +2 -1
- data/app/models/spree/promotion.rb +29 -55
- data/app/models/spree/promotion_rule.rb +11 -0
- data/app/views/spree/admin/promotion_actions/create.js.erb +2 -1
- data/app/views/spree/admin/promotion_rules/create.js.erb +2 -0
- data/app/views/spree/admin/promotion_rules/destroy.js.erb +2 -0
- data/app/views/spree/admin/promotions/_actions.html.erb +1 -6
- data/app/views/spree/admin/promotions/_form.html.erb +5 -0
- data/app/views/spree/admin/promotions/_promotion_action.html.erb +5 -6
- data/app/views/spree/admin/promotions/_rules.html.erb +3 -3
- data/app/views/spree/admin/promotions/actions/_create_adjustment.html.erb +14 -6
- data/app/views/spree/admin/promotions/actions/_create_line_items.html.erb +2 -2
- data/config/locales/en.yml +2 -0
- data/db/migrate/20120119024707_namespace_promo_tables.rb +65 -0
- data/db/migrate/20120119024708_create_spree_pending_promotions.rb +11 -0
- data/db/migrate/20120119024721_content_visited_event.rb +29 -0
- data/lib/spree/promo/engine.rb +1 -7
- metadata +12 -11
- data/app/models/spree/promotion/rules/landing_page.rb +0 -16
- data/app/views/spree/admin/promotions/actions/_give_store_credit.html.erb +0 -6
- 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").
|
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("
|
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])
|
@@ -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
|
-
|
9
|
-
|
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
|
-
|
16
|
-
|
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 :
|
2
|
+
after_filter :fire_visited_event
|
4
3
|
|
5
|
-
def
|
6
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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.
|
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
|
-
|
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
|
-
|
6
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
71
|
-
|
72
|
-
if
|
73
|
-
|
74
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
54
|
+
if path.present?
|
55
|
+
return unless path == payload[:path]
|
56
|
+
end
|
82
57
|
|
83
|
-
|
84
|
-
|
58
|
+
actions.each do |action|
|
59
|
+
action.perform(payload)
|
60
|
+
end
|
61
|
+
end
|
85
62
|
|
86
|
-
|
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
|
-
|
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
|
-
$('#
|
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) %>');
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
7
|
+
<%= hidden_field_tag "#{param_prefix}[id]", promotion_action.id %>
|
9
8
|
<p><%= t("promotion_action_types.#{type_name}.description") %></p>
|
10
|
-
|
11
|
-
|
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 :
|
7
|
+
<label><%= f.radio_button :match_policy, policy %> <%= t "promotion_form.match_policies.#{policy}" %></label>
|
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
|
-
|
24
|
+
|
25
25
|
<p>
|
26
26
|
<%= label_tag :promotion_rule_type, t(:add_rule_of_type) %>
|
27
|
-
<%= select_tag('promotion_rule[type]',
|
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
|
-
|
5
|
-
<%=
|
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
|
<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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
<%=
|
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
|
<br />
|
39
40
|
<button class="add small"> <%= t(:add) %></button>
|
40
41
|
</div>
|
41
|
-
|
42
42
|
</fieldset>
|
43
43
|
</div>
|
data/config/locales/en.yml
CHANGED
@@ -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
|
data/lib/spree/promo/engine.rb
CHANGED
@@ -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.
|
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-
|
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: &
|
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.
|
21
|
+
version: 1.0.0.rc3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70260369514180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: spree_auth
|
27
|
-
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.
|
32
|
+
version: 1.0.0.rc3
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
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/
|
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,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
|