spree_promo 0.70.7 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +2 -2
- data/app/assets/javascripts/admin/promotions.js +3 -23
- data/app/controllers/spree/admin/promotion_actions_controller.rb +27 -0
- data/app/controllers/spree/admin/promotion_rules_controller.rb +26 -0
- data/app/controllers/spree/admin/promotions_controller.rb +24 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +39 -0
- data/app/controllers/{content_controller_decorator.rb → spree/content_controller_decorator.rb} +4 -2
- data/app/controllers/{orders_controller_decorator.rb → spree/orders_controller_decorator.rb} +1 -3
- data/app/models/{adjustment_decorator.rb → spree/adjustment_decorator.rb} +1 -1
- data/app/models/spree/calculator/free_shipping.rb +18 -0
- data/app/models/{order_decorator.rb → spree/order_decorator.rb} +5 -4
- data/app/models/{product_decorator.rb → spree/product_decorator.rb} +3 -3
- data/app/models/spree/product_group_decorator.rb +3 -0
- data/app/models/spree/promotion/actions/create_adjustment.rb +33 -0
- data/app/models/spree/promotion/actions/create_line_items.rb +28 -0
- data/app/models/spree/promotion/rules/first_order.rb +7 -0
- data/app/models/spree/promotion/rules/item_total.rb +14 -0
- data/app/models/spree/promotion/rules/landing_page.rb +16 -0
- data/app/models/spree/promotion/rules/product.rb +40 -0
- data/app/models/spree/promotion/rules/user.rb +18 -0
- data/app/models/spree/promotion/rules/user_logged_in.rb +15 -0
- data/app/models/spree/promotion.rb +131 -0
- data/app/models/spree/promotion_action.rb +17 -0
- data/app/models/spree/promotion_action_line_item.rb +6 -0
- data/app/models/spree/promotion_rule.rb +12 -0
- data/app/overrides/promo_admin_tabs.rb +2 -2
- data/app/overrides/promo_coupon_code_field.rb +2 -2
- data/app/overrides/promo_product_properties.rb +2 -2
- data/app/views/{admin → spree/admin}/promotion_actions/create.js.erb +1 -1
- data/app/views/{admin → spree/admin}/promotion_actions/destroy.js.erb +0 -0
- data/app/views/{admin → spree/admin}/promotion_rules/create.js.erb +1 -1
- data/app/views/{admin → spree/admin}/promotion_rules/destroy.js.erb +0 -0
- data/app/views/{admin → spree/admin}/promotions/_actions.html.erb +5 -5
- data/app/views/{admin → spree/admin}/promotions/_form.html.erb +11 -11
- data/app/views/{admin → spree/admin}/promotions/_promotion_action.html.erb +2 -2
- data/app/views/{admin → spree/admin}/promotions/_promotion_rule.html.erb +2 -2
- data/app/views/{admin → spree/admin}/promotions/_rules.html.erb +2 -2
- data/app/views/{admin → spree/admin}/promotions/_tab.html.erb +0 -0
- data/app/views/{admin → spree/admin}/promotions/actions/_create_adjustment.html.erb +1 -1
- data/app/views/{admin → spree/admin}/promotions/actions/_create_line_items.html.erb +1 -0
- data/app/views/{admin → spree/admin}/promotions/actions/_give_store_credit.html.erb +1 -1
- data/app/views/{admin → spree/admin}/promotions/edit.html.erb +3 -3
- data/app/views/{admin → spree/admin}/promotions/index.html.erb +2 -2
- data/app/views/{admin → spree/admin}/promotions/new.html.erb +1 -1
- data/app/views/{admin → spree/admin}/promotions/rules/_first_order.html.erb +0 -0
- data/app/views/{admin → spree/admin}/promotions/rules/_item_total.html.erb +1 -1
- data/app/views/{admin → spree/admin}/promotions/rules/_landing_page.html.erb +0 -0
- data/app/views/{admin → spree/admin}/promotions/rules/_product.html.erb +2 -2
- data/app/views/{admin → spree/admin}/promotions/rules/_user.html.erb +0 -0
- data/app/views/{admin → spree/admin}/promotions/rules/_user_logged_in.html.erb +0 -0
- data/app/views/{checkout → spree/checkout}/_coupon_code_field.html.erb +1 -1
- data/app/views/{products → spree/products}/_promotions.html.erb +0 -0
- data/config/locales/en.yml +7 -0
- data/config/routes.rb +1 -1
- data/db/migrate/20100419190933_rename_coupons_to_promotions.rb +4 -4
- data/db/migrate/20100426100726_create_promotion_rules.rb +4 -4
- data/db/migrate/20100501084722_match_policy_for_promotions.rb +3 -7
- data/db/migrate/20100501095202_create_promotion_rules_users.rb +3 -3
- data/db/migrate/20100502163939_name_for_promotions.rb +3 -7
- data/db/migrate/20100923095305_update_calculable_type_for_promotions.rb +4 -4
- data/db/migrate/20101026184833_migrate_adjustments.rb +4 -4
- data/db/migrate/20110331094351_promotion_changes_to_subclass_of_activator.rb +13 -13
- data/db/migrate/20110404123358_create_promotion_actions.rb +2 -6
- data/db/migrate/20110601202923_create_promotion_action_line_items.rb +4 -6
- data/db/migrate/20111013155037_namespace_promo_tables.rb +9 -0
- data/lib/spree/promo/engine.rb +59 -0
- data/lib/spree/promo/environment.rb +1 -1
- data/lib/spree/promo.rb +10 -0
- data/lib/spree_promo.rb +1 -71
- metadata +77 -72
- data/app/controllers/admin/promotion_actions_controller.rb +0 -28
- data/app/controllers/admin/promotion_rules_controller.rb +0 -26
- data/app/controllers/admin/promotions_controller.rb +0 -21
- data/app/controllers/checkout_controller_decorator.rb +0 -13
- data/app/models/calculator/free_shipping.rb +0 -19
- data/app/models/pending_promotion.rb +0 -4
- data/app/models/product_group_decorator.rb +0 -3
- data/app/models/promotion/actions/create_adjustment.rb +0 -28
- data/app/models/promotion/actions/create_line_items.rb +0 -29
- data/app/models/promotion/rules/first_order.rb +0 -7
- data/app/models/promotion/rules/item_total.rb +0 -13
- data/app/models/promotion/rules/landing_page.rb +0 -17
- data/app/models/promotion/rules/product.rb +0 -40
- data/app/models/promotion/rules/user.rb +0 -17
- data/app/models/promotion/rules/user_logged_in.rb +0 -13
- data/app/models/promotion.rb +0 -97
- data/app/models/promotion_action.rb +0 -17
- data/app/models/promotion_action_line_item.rb +0 -6
- data/app/models/promotion_rule.rb +0 -11
- data/app/models/user_decorator.rb +0 -4
- data/config/cucumber.yml +0 -10
- data/db/migrate/20120119024708_create_pending_promotions.rb +0 -11
- data/lib/tasks/promotions.rake +0 -11
- data/lib/tasks/promotions_extension_tasks.rake +0 -17
data/app/models/promotion.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
class Promotion < Activator
|
2
|
-
|
3
|
-
|
4
|
-
MATCH_POLICIES = %w(all any)
|
5
|
-
|
6
|
-
preference :usage_limit, :integer
|
7
|
-
preference :match_policy, :string, :default => MATCH_POLICIES.first
|
8
|
-
preference :code, :string
|
9
|
-
preference :advertise, :boolean, :default => false
|
10
|
-
|
11
|
-
[:usage_limit, :match_policy, :code, :advertise].each do |field|
|
12
|
-
alias_method field, "preferred_#{field}"
|
13
|
-
alias_method "#{field}=", "preferred_#{field}="
|
14
|
-
end
|
15
|
-
|
16
|
-
has_many :promotion_rules, :foreign_key => 'activator_id', :autosave => true, :dependent => :destroy
|
17
|
-
alias_method :rules, :promotion_rules
|
18
|
-
accepts_nested_attributes_for :promotion_rules
|
19
|
-
|
20
|
-
has_many :promotion_actions, :foreign_key => 'activator_id', :autosave => true, :dependent => :destroy
|
21
|
-
alias_method :actions, :promotion_actions
|
22
|
-
accepts_nested_attributes_for :promotion_actions
|
23
|
-
|
24
|
-
# TODO: This shouldn't be necessary with :autosave option but nested attribute updating of actions is broken without it
|
25
|
-
after_save :save_rules_and_actions
|
26
|
-
def save_rules_and_actions
|
27
|
-
(rules + actions).each &:save
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
validates :name, :presence => true
|
32
|
-
validates :preferred_code, :presence => true, :if => lambda{|r| r.event_name == 'spree.ceckout.coupon_code_added' }
|
33
|
-
|
34
|
-
class << self
|
35
|
-
def advertised
|
36
|
-
includes(:stored_preferences).where(:preferences => {:name => 'advertise', :value => '1'})
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# 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
|
41
|
-
# is provided
|
42
|
-
def save(*)
|
43
|
-
if super
|
44
|
-
promotion_rules.each { |p| p.save }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
def activate(payload)
|
50
|
-
if eligible?(payload[:order], payload)
|
51
|
-
actions.each do |action|
|
52
|
-
action.perform(payload)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def eligible?(order, options = {})
|
58
|
-
!expired? && rules_are_eligible?(order, options) && coupon_is_eligible?(order, options[:coupon_code])
|
59
|
-
end
|
60
|
-
|
61
|
-
def rules_are_eligible?(order, options = {})
|
62
|
-
return true if rules.none?
|
63
|
-
if match_policy == 'all'
|
64
|
-
rules.all?{|r| r.eligible?(order, options)}
|
65
|
-
else
|
66
|
-
rules.any?{|r| r.eligible?(order, options)}
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def coupon_is_eligible?(order, code = nil)
|
71
|
-
return true if order && order.promotion_credit_exists?(self)
|
72
|
-
return true if event_name != 'spree.checkout.coupon_code_added'
|
73
|
-
code.to_s.strip.downcase == preferred_code.to_s.strip.downcase
|
74
|
-
end
|
75
|
-
|
76
|
-
# Products assigned to all product rules
|
77
|
-
def products
|
78
|
-
@products ||= rules.of_type("Promotion::Rules::Product").map(&:products).flatten.uniq
|
79
|
-
end
|
80
|
-
|
81
|
-
def expired?
|
82
|
-
super || usage_limit_exceeded?
|
83
|
-
end
|
84
|
-
|
85
|
-
def usage_limit_exceeded?
|
86
|
-
preferred_usage_limit.present? && preferred_usage_limit > 0 && credits_count >= preferred_usage_limit
|
87
|
-
end
|
88
|
-
|
89
|
-
def credits
|
90
|
-
Adjustment.where(:originator_type => 'Promotion', :originator_id => actions.map(&:id))
|
91
|
-
end
|
92
|
-
|
93
|
-
def credits_count
|
94
|
-
credits.count
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# Base class for all types of promotion action.
|
2
|
-
# PromotionActions perform the necessary tasks when a promotion is activated by an event and determined to be eligible.
|
3
|
-
class PromotionAction < ActiveRecord::Base
|
4
|
-
belongs_to :promotion, :foreign_key => 'activator_id'
|
5
|
-
|
6
|
-
scope :of_type, lambda {|t| {:conditions => {:type => t}}}
|
7
|
-
|
8
|
-
# This method should be overriden in subclass
|
9
|
-
# Updates the state of the order or performs some other action depending on the subclass
|
10
|
-
# options will contain the payload from the event that activated the promotion. This will include
|
11
|
-
# the key :user which allows user based actions to be performed in addition to actions on the order
|
12
|
-
def perform(options = {})
|
13
|
-
raise 'perform should be implemented in a sub-class of PromotionAction'
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# Base class for all promotion rules
|
2
|
-
class PromotionRule < ActiveRecord::Base
|
3
|
-
belongs_to :promotion, :foreign_key => 'activator_id'
|
4
|
-
|
5
|
-
scope :of_type, lambda {|t| {:conditions => {:type => t}}}
|
6
|
-
|
7
|
-
def eligible?(order, options = {})
|
8
|
-
raise 'eligible? should be implemented in a sub-class of Promotion::PromotionRule'
|
9
|
-
end
|
10
|
-
|
11
|
-
end
|
data/config/cucumber.yml
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
<%
|
2
|
-
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
-
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
-
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
|
5
|
-
ci_opts = "--format progress --strict"
|
6
|
-
%>
|
7
|
-
default: <%= std_opts %> features
|
8
|
-
wip: --tags @wip:3 --wip features
|
9
|
-
ci: <%= ci_opts %> features CI=true
|
10
|
-
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
@@ -1,11 +0,0 @@
|
|
1
|
-
class CreatePendingPromotions < ActiveRecord::Migration
|
2
|
-
def change
|
3
|
-
create_table :pending_promotions do |t|
|
4
|
-
t.references :user
|
5
|
-
t.references :promotion
|
6
|
-
end
|
7
|
-
|
8
|
-
add_index :pending_promotions, :user_id
|
9
|
-
add_index :pending_promotions, :promotion_id
|
10
|
-
end
|
11
|
-
end
|
data/lib/tasks/promotions.rake
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
namespace :spree do
|
2
|
-
desc "Synchronize public assets, migrations, seed and sample data from the Spree gems"
|
3
|
-
task :sync do
|
4
|
-
public_dir = File.join(File.dirname(__FILE__), '..', '..', 'public')
|
5
|
-
migration_dir = File.join(File.dirname(__FILE__), '..', '..', 'db', 'migrate')
|
6
|
-
puts "Mirror: #{public_dir}"
|
7
|
-
Spree::FileUtilz.mirror_with_backup(public_dir, File.join(Rails.root, 'public'))
|
8
|
-
puts "Mirror: #{migration_dir}"
|
9
|
-
Spree::FileUtilz.mirror_with_backup(migration_dir, File.join(Rails.root, 'db', 'migrate'))
|
10
|
-
end
|
11
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
namespace :spree do
|
2
|
-
namespace :extensions do
|
3
|
-
namespace :promotions do
|
4
|
-
desc "Copies public assets of the Promotions to the instance public/ directory."
|
5
|
-
task :update => :environment do
|
6
|
-
is_svn_git_or_dir = proc {|path| path =~ /\.svn/ || path =~ /\.git/ || File.directory?(path) }
|
7
|
-
Dir[PromotionsExtension.root + "/public/**/*"].reject(&is_svn_git_or_dir).each do |file|
|
8
|
-
path = file.sub(PromotionsExtension.root, '')
|
9
|
-
directory = File.dirname(path)
|
10
|
-
puts "Copying #{path}..."
|
11
|
-
mkdir_p Rails.root + directory
|
12
|
-
cp file, Rails.root + path
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|