spree_promo 1.2.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.exists?(:code => @order.coupon_code,
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) { |format| format.html { redirect_to cart_path } }
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.exists?(:code => @order.coupon_code)
25
- fire_event('spree.checkout.coupon_code_added', :coupon_code => @order.coupon_code)
26
- true
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
 
@@ -1,3 +1,7 @@
1
1
  Spree::Adjustment.class_eval do
2
- scope :promotion, lambda { where('label LIKE ?', "#{I18n.t(:promotion)}%") }
2
+ class << self
3
+ def promotion
4
+ where(:originator_type => 'Spree::PromotionAction')
5
+ end
6
+ end
3
7
  end
@@ -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
- if adjustment.originator.calculator.is_a?(Spree::Calculator::PerItem)
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
@@ -0,0 +1,5 @@
1
+ Spree::Payment.class_eval do
2
+ def promo_total
3
+ order.promo_total * 100
4
+ end
5
+ 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
- all_rules = promotion_rules
6
- promotion_ids = all_rules.map(&:activator_id).uniq
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
- # TODO: Remove that after fix for https://rails.lighthouseapp.com/projects/8994/tickets/4329-has_many-through-association-does-not-link-models-on-association-save
40
- # is provided
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)
@@ -1,4 +1,5 @@
1
- # A rule to limit a promotion to a specific user.
1
+ # A rule to apply to an order greater than (or greater than or equal to)
2
+ # a specific amount
2
3
  module Spree
3
4
  class Promotion
4
5
  module Rules
@@ -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
- <p class="field">
2
- <label>
3
- <%= t('user_rule.choose_users') %><br />
4
- <% user_names_hash = promotion_rule.users.inject({}){|memo,item| memo[item.id] = item.email; memo} %>
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
- <%= form.label :coupon_code %><br />
4
- <%= form.text_field :coupon_code %>
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 %>
@@ -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"
@@ -33,6 +33,7 @@ module Spree
33
33
  Spree::Calculator::FlatRate,
34
34
  Spree::Calculator::FlexiRate,
35
35
  Spree::Calculator::PerItem,
36
+ Spree::Calculator::PercentPerItem,
36
37
  Spree::Calculator::FreeShipping
37
38
  ]
38
39
  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.2.0
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-08-30 00:00:00.000000000Z
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: &70361905875780 !ruby/object:Gem::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.0
21
+ version: 1.2.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70361905875780
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: 2575003637093529431
129
+ hash: -4584730679565675092
128
130
  requirements:
129
131
  - none
130
132
  rubyforge_project: