spree_promo 1.2.0 → 1.2.2
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.
- data/app/assets/javascripts/admin/spree_promo.js +35 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +1 -3
- data/app/controllers/spree/orders_controller_decorator.rb +14 -4
- data/app/models/spree/adjustment_decorator.rb +5 -1
- data/app/models/spree/calculator/percent_per_item.rb +48 -0
- data/app/models/spree/order_decorator.rb +5 -3
- data/app/models/spree/payment_decorator.rb +5 -0
- data/app/models/spree/product_decorator.rb +2 -3
- data/app/models/spree/promotion.rb +2 -6
- data/app/models/spree/promotion/rules/item_total.rb +2 -1
- data/app/views/spree/admin/promotions/_form.html.erb +2 -1
- data/app/views/spree/admin/promotions/rules/_user.html.erb +4 -8
- data/app/views/spree/checkout/_coupon_code_field.html.erb +4 -4
- data/config/locales/en.yml +2 -0
- data/lib/spree/promo/engine.rb +1 -0
- metadata +8 -6
|
@@ -1,2 +1,37 @@
|
|
|
1
1
|
//= require admin/spree_core
|
|
2
2
|
//= require_tree .
|
|
3
|
+
|
|
4
|
+
function cleanUsers(data) {
|
|
5
|
+
var users = $.map(data['users'], function(result) {
|
|
6
|
+
return result['user']
|
|
7
|
+
})
|
|
8
|
+
return users;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
$(document).ready(function() {
|
|
12
|
+
$('.user_picker').select2({
|
|
13
|
+
minimumInputLength: 1,
|
|
14
|
+
multiple: true,
|
|
15
|
+
initSelection: function(element, callback) {
|
|
16
|
+
$.get(Spree.routes.user_search, { ids: element.val() }, function(data) {
|
|
17
|
+
callback(cleanUsers(data))
|
|
18
|
+
})
|
|
19
|
+
},
|
|
20
|
+
ajax: {
|
|
21
|
+
url: Spree.routes.user_search,
|
|
22
|
+
datatype: 'json',
|
|
23
|
+
data: function(term, page) {
|
|
24
|
+
return { q: term }
|
|
25
|
+
},
|
|
26
|
+
results: function(data, page) {
|
|
27
|
+
return { results: cleanUsers(data) }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
formatResult: function(user) {
|
|
31
|
+
return user.email;
|
|
32
|
+
},
|
|
33
|
+
formatSelection: function(user) {
|
|
34
|
+
return user.email;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
})
|
|
@@ -8,9 +8,7 @@ Spree::CheckoutController.class_eval do
|
|
|
8
8
|
|
|
9
9
|
if @order.coupon_code.present?
|
|
10
10
|
event_name = "spree.checkout.coupon_code_added"
|
|
11
|
-
if Spree::Promotion.
|
|
12
|
-
:event_name => event_name)
|
|
13
|
-
|
|
11
|
+
if promo = Spree::Promotion.with_coupon_code(@order.coupon_code).where(:event_name => event_name).first
|
|
14
12
|
fire_event(event_name, :coupon_code => @order.coupon_code)
|
|
15
13
|
# If it doesn't exist, raise an error!
|
|
16
14
|
# Giving them another chance to enter a valid coupon code
|
|
@@ -13,7 +13,15 @@ Spree::OrdersController.class_eval do
|
|
|
13
13
|
end
|
|
14
14
|
@order.line_items = @order.line_items.select {|li| li.quantity > 0 }
|
|
15
15
|
fire_event('spree.order.contents_changed')
|
|
16
|
-
respond_with(@order)
|
|
16
|
+
respond_with(@order) do |format|
|
|
17
|
+
format.html do
|
|
18
|
+
if params.has_key?(:checkout)
|
|
19
|
+
redirect_to checkout_state_path(@order.checkout_steps.first)
|
|
20
|
+
else
|
|
21
|
+
redirect_to cart_path
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
17
25
|
else
|
|
18
26
|
respond_with(@order)
|
|
19
27
|
end
|
|
@@ -21,9 +29,11 @@ Spree::OrdersController.class_eval do
|
|
|
21
29
|
|
|
22
30
|
def apply_coupon_code
|
|
23
31
|
return if @order.coupon_code.blank?
|
|
24
|
-
if Spree::Promotion.
|
|
25
|
-
|
|
26
|
-
|
|
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
|
|
27
37
|
end
|
|
28
38
|
end
|
|
29
39
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
|
|
3
|
+
# A calculator for promotions that calculates a percent-off discount
|
|
4
|
+
# for all matching products in an order. This should not be used as a
|
|
5
|
+
# shipping calculator since it would be the same thing as a flat percent
|
|
6
|
+
# off the entire order.
|
|
7
|
+
|
|
8
|
+
class Calculator::PercentPerItem < Calculator
|
|
9
|
+
preference :percent, :decimal, :default => 0
|
|
10
|
+
|
|
11
|
+
attr_accessible :preferred_percent
|
|
12
|
+
|
|
13
|
+
def self.description
|
|
14
|
+
I18n.t(:percent_per_item)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def compute(object=nil)
|
|
18
|
+
return 0 if object.nil?
|
|
19
|
+
object.line_items.reduce(0) do |sum, line_item|
|
|
20
|
+
sum += value_for_line_item(line_item)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# Returns all products that match the promotion's rule.
|
|
27
|
+
def matching_products
|
|
28
|
+
@matching_products ||= if compute_on_promotion?
|
|
29
|
+
self.calculable.promotion.rules.map(&:products).flatten
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Calculates the discount value of each line item. Returns zero
|
|
34
|
+
# unless the product is included in the promotion rules.
|
|
35
|
+
def value_for_line_item(line_item)
|
|
36
|
+
if compute_on_promotion?
|
|
37
|
+
return 0 unless matching_products.include?(line_item.product)
|
|
38
|
+
end
|
|
39
|
+
line_item.price * line_item.quantity * preferred_percent
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Determines wether or not the calculable object is a promotion
|
|
43
|
+
def compute_on_promotion?
|
|
44
|
+
@compute_on_promotion ||= self.calculable.respond_to?(:promotion)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -16,11 +16,13 @@ Spree::Order.class_eval do
|
|
|
16
16
|
most_valuable_adjustment = adjustments.promotion.eligible.max{|a,b| a.amount.abs <=> b.amount.abs}
|
|
17
17
|
current_adjustments = (adjustments.promotion.eligible - [most_valuable_adjustment])
|
|
18
18
|
current_adjustments.each do |adjustment|
|
|
19
|
-
|
|
20
|
-
adjustment.update_attribute_without_callbacks(:eligible, false)
|
|
21
|
-
end
|
|
19
|
+
adjustment.update_attribute_without_callbacks(:eligible, false)
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
alias_method_chain :update_adjustments, :promotion_limiting
|
|
25
23
|
end
|
|
24
|
+
|
|
25
|
+
def promo_total
|
|
26
|
+
adjustments.eligible.promotion.map(&:amount).sum
|
|
27
|
+
end
|
|
26
28
|
end
|
|
@@ -2,8 +2,7 @@ Spree::Product.class_eval do
|
|
|
2
2
|
has_and_belongs_to_many :promotion_rules, :join_table => :spree_products_promotion_rules
|
|
3
3
|
|
|
4
4
|
def possible_promotions
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Spree::Promotion.advertised.where(:id => promotion_ids)
|
|
5
|
+
promotion_ids = promotion_rules.map(&:activator_id).uniq
|
|
6
|
+
Spree::Promotion.advertised.where(:id => promotion_ids).reject(&:expired?)
|
|
8
7
|
end
|
|
9
8
|
end
|
|
@@ -36,12 +36,8 @@ module Spree
|
|
|
36
36
|
where(:advertise => true)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def save(*)
|
|
42
|
-
if super
|
|
43
|
-
promotion_rules.each(&:save)
|
|
44
|
-
end
|
|
39
|
+
def self.with_coupon_code(coupon_code)
|
|
40
|
+
search(:code_cont => coupon_code).result
|
|
45
41
|
end
|
|
46
42
|
|
|
47
43
|
def activate(payload)
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
<legend><%= t(:expiry) %></legend>
|
|
38
38
|
<p>
|
|
39
39
|
<%= f.label :usage_limit %><br />
|
|
40
|
-
<%= f.text_field :usage_limit
|
|
40
|
+
<%= f.text_field :usage_limit %><br/>
|
|
41
|
+
<%= t(:current_promotion_usage, :count => @promotion.credits_count) %>
|
|
41
42
|
</p>
|
|
42
43
|
|
|
43
44
|
<p id="starts_at_field">
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
<
|
|
2
|
-
<label>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<% user_rules = promotion_rule.users.collect { |u| { :id => u.id, :name => u.email } } %>
|
|
6
|
-
<input type="text" name="<%= param_prefix %>[user_ids_string]" value="<%= promotion_rule.user_ids_string %>" class="tokeninput users" data-names='<%= user_names_hash.to_json %>' data-pre='<%= user_rules.to_json %>'/>
|
|
7
|
-
</label>
|
|
8
|
-
</p>
|
|
1
|
+
<div class="field alpha omega eight columns">
|
|
2
|
+
<label><%= t('user_rule.choose_users') %></label><br>
|
|
3
|
+
<input type='hidden' name='<%= param_prefix %>[user_ids_string]' class='user_picker fullwidth' value='<%= promotion_rule.user_ids.join(",") %>'>
|
|
4
|
+
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<% if Spree::Promotion.count > 0 %>
|
|
2
|
-
<p>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
</p>
|
|
2
|
+
<p class='field' data-hook='coupon_code'>
|
|
3
|
+
<%= form.label :coupon_code %><br />
|
|
4
|
+
<%= form.text_field :coupon_code %>
|
|
5
|
+
</p>
|
|
6
6
|
<% end %>
|
data/config/locales/en.yml
CHANGED
|
@@ -18,6 +18,7 @@ en:
|
|
|
18
18
|
coupon_code: Coupon code
|
|
19
19
|
coupon_code_applied: The coupon code was successfully applied to your order.
|
|
20
20
|
editing_promotion: Editing Promotion
|
|
21
|
+
current_promotion_usage: 'Current Usage: %{count}'
|
|
21
22
|
events:
|
|
22
23
|
spree:
|
|
23
24
|
checkout:
|
|
@@ -34,6 +35,7 @@ en:
|
|
|
34
35
|
path: Path
|
|
35
36
|
new_promotion: New Promotion
|
|
36
37
|
no_rules_added: No rules added
|
|
38
|
+
percent_per_item: Percent Per Item
|
|
37
39
|
product_rule:
|
|
38
40
|
choose_products: Choose products
|
|
39
41
|
label: "Order must contain %{select} of these products"
|
data/lib/spree/promo/engine.rb
CHANGED
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.2.
|
|
4
|
+
version: 1.2.2
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,19 +9,19 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-11-19 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: spree_core
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70301845341720 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - =
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.2.
|
|
21
|
+
version: 1.2.2
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70301845341720
|
|
25
25
|
description: Required dependency for Spree
|
|
26
26
|
email: david@spreecommerce.com
|
|
27
27
|
executables: []
|
|
@@ -44,7 +44,9 @@ files:
|
|
|
44
44
|
- app/helpers/spree/promotion_rules_helper.rb
|
|
45
45
|
- app/models/spree/adjustment_decorator.rb
|
|
46
46
|
- app/models/spree/calculator/free_shipping.rb
|
|
47
|
+
- app/models/spree/calculator/percent_per_item.rb
|
|
47
48
|
- app/models/spree/order_decorator.rb
|
|
49
|
+
- app/models/spree/payment_decorator.rb
|
|
48
50
|
- app/models/spree/product_decorator.rb
|
|
49
51
|
- app/models/spree/promotion/actions/create_adjustment.rb
|
|
50
52
|
- app/models/spree/promotion/actions/create_line_items.rb
|
|
@@ -124,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
124
126
|
version: '0'
|
|
125
127
|
segments:
|
|
126
128
|
- 0
|
|
127
|
-
hash:
|
|
129
|
+
hash: -4584730679565675092
|
|
128
130
|
requirements:
|
|
129
131
|
- none
|
|
130
132
|
rubyforge_project:
|